makefx 1.0.5 → 1.0.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/README.md +1 -1
- package/makefx.mjs +658 -178
- package/package.json +1 -1
package/makefx.mjs
CHANGED
|
@@ -844,7 +844,7 @@ function validateProjectConfig(config, configPath) {
|
|
|
844
844
|
* makefx spaces inspect-deleted <space_id> Inspect a soft-deleted space
|
|
845
845
|
* makefx spaces restore <space_id> Restore a soft-deleted space
|
|
846
846
|
*/
|
|
847
|
-
var defaultDeps$
|
|
847
|
+
var defaultDeps$10 = {
|
|
848
848
|
loadConfig: loadStoredConfig,
|
|
849
849
|
resolveBaseUrl,
|
|
850
850
|
saveProjectConfig,
|
|
@@ -859,7 +859,7 @@ async function handleSpaces(parsed) {
|
|
|
859
859
|
process$1.exitCode = 1;
|
|
860
860
|
}
|
|
861
861
|
}
|
|
862
|
-
async function executeSpaces(parsed, deps = defaultDeps$
|
|
862
|
+
async function executeSpaces(parsed, deps = defaultDeps$10) {
|
|
863
863
|
const env = resolveCommandEnvironment(parsed);
|
|
864
864
|
const showDetails = parsed.options.details === "true";
|
|
865
865
|
const spaceId = parsed.options.id;
|
|
@@ -5386,7 +5386,7 @@ function isMirrorEntry(value) {
|
|
|
5386
5386
|
* makefx upload <file> --space <id> --name <name> Upload as new asset
|
|
5387
5387
|
* makefx upload <file> --space <id> --name <name> --type <type>
|
|
5388
5388
|
*/
|
|
5389
|
-
var defaultDeps$
|
|
5389
|
+
var defaultDeps$9 = {
|
|
5390
5390
|
loadConfig: loadStoredConfig,
|
|
5391
5391
|
loadProjectConfig,
|
|
5392
5392
|
resolveBaseUrl,
|
|
@@ -5415,11 +5415,11 @@ async function handleUpload(parsed) {
|
|
|
5415
5415
|
await executeUpload(parsed);
|
|
5416
5416
|
} catch (error) {
|
|
5417
5417
|
console.error(error instanceof Error ? `Error: ${error.message}` : "Error: Upload failed");
|
|
5418
|
-
if (error instanceof UploadUsageError) printUsage$
|
|
5418
|
+
if (error instanceof UploadUsageError) printUsage$9();
|
|
5419
5419
|
process$1.exitCode = 1;
|
|
5420
5420
|
}
|
|
5421
5421
|
}
|
|
5422
|
-
async function executeUpload(parsed, deps = defaultDeps$
|
|
5422
|
+
async function executeUpload(parsed, deps = defaultDeps$9) {
|
|
5423
5423
|
const filePath = parsed.positionals[0];
|
|
5424
5424
|
if (!filePath) throw new UploadUsageError("File path is required");
|
|
5425
5425
|
rejectRetiredUploadOrganizationOptions(parsed);
|
|
@@ -5454,17 +5454,11 @@ async function executeUpload(parsed, deps = defaultDeps$8) {
|
|
|
5454
5454
|
if (config.token.expiresAt < Date.now()) throw new Error(`Token expired for ${env} environment. Run: ${loginCommandForEnvironment(env)}`);
|
|
5455
5455
|
const baseUrl = deps.resolveBaseUrl(env);
|
|
5456
5456
|
const accessToken = config.token.accessToken;
|
|
5457
|
-
const ctx = {
|
|
5458
|
-
spaceId,
|
|
5459
|
-
baseUrl,
|
|
5460
|
-
accessToken
|
|
5461
|
-
};
|
|
5462
5457
|
if (env === "local") process$1.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
5463
5458
|
try {
|
|
5464
5459
|
const fileStat = await deps.stat(filePath);
|
|
5465
5460
|
if (!fileStat.isFile()) throw new Error(`"${filePath}" is not a file`);
|
|
5466
5461
|
if (fileStat.size > 10485760) throw new Error(`File too large (${(fileStat.size / 1024 / 1024).toFixed(2)}MB). Maximum size: 10MB`);
|
|
5467
|
-
await preflightSourceVariants(ctx, deps, sourceVariantIds);
|
|
5468
5462
|
const fileBuffer = await deps.readFile(filePath);
|
|
5469
5463
|
const fileName = path.basename(filePath);
|
|
5470
5464
|
const formData = new FormData();
|
|
@@ -5605,30 +5599,7 @@ function parseCsvOption(value, optionName) {
|
|
|
5605
5599
|
if (value === "true") throw new UploadUsageError(`${optionName} requires a value`);
|
|
5606
5600
|
return value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
5607
5601
|
}
|
|
5608
|
-
|
|
5609
|
-
if (sourceVariantIds.length === 0) return;
|
|
5610
|
-
const state = await fetchVariantState(ctx, deps);
|
|
5611
|
-
for (const sourceVariantId of sourceVariantIds) if (!state.variantsById.has(sourceVariantId)) throw new Error(`Source variant not found in space: ${sourceVariantId}`);
|
|
5612
|
-
}
|
|
5613
|
-
async function fetchVariantState(ctx, deps) {
|
|
5614
|
-
const assets = (await fetchJson$1(ctx, deps, `/api/spaces/${ctx.spaceId}/assets`)).assets ?? [];
|
|
5615
|
-
const variantsById = /* @__PURE__ */ new Map();
|
|
5616
|
-
await Promise.all(assets.map(async (asset) => {
|
|
5617
|
-
const details = await fetchJson$1(ctx, deps, `/api/spaces/${ctx.spaceId}/assets/${encodeURIComponent(asset.id)}`);
|
|
5618
|
-
for (const variant of details.variants ?? []) variantsById.set(variant.id, variant);
|
|
5619
|
-
}));
|
|
5620
|
-
return { variantsById };
|
|
5621
|
-
}
|
|
5622
|
-
async function fetchJson$1(ctx, deps, requestPath) {
|
|
5623
|
-
const response = await deps.fetch(`${ctx.baseUrl}${requestPath}`, { headers: {
|
|
5624
|
-
Authorization: `Bearer ${ctx.accessToken}`,
|
|
5625
|
-
Accept: "application/json"
|
|
5626
|
-
} });
|
|
5627
|
-
const data = await response.json().catch(() => ({}));
|
|
5628
|
-
if (!response.ok) throw new Error("error" in data ? data.error : `Request failed: ${response.status}`);
|
|
5629
|
-
return data;
|
|
5630
|
-
}
|
|
5631
|
-
function printUsage$8() {
|
|
5602
|
+
function printUsage$9() {
|
|
5632
5603
|
console.log(`
|
|
5633
5604
|
Usage:
|
|
5634
5605
|
makefx upload <file> --asset <id> [--space <id>] Upload media to existing asset
|
|
@@ -5945,6 +5916,15 @@ var ServerConfirmationTimeoutError = class extends Error {
|
|
|
5945
5916
|
this.name = "ServerConfirmationTimeoutError";
|
|
5946
5917
|
}
|
|
5947
5918
|
};
|
|
5919
|
+
function collectionItemMatchesInput(item, input) {
|
|
5920
|
+
if (item.subject_type !== input.subjectType) return false;
|
|
5921
|
+
if (input.subjectType === "asset" && item.asset_id !== input.assetId) return false;
|
|
5922
|
+
if (input.subjectType === "variant" && item.variant_id !== input.variantId) return false;
|
|
5923
|
+
if (input.role !== void 0 && item.role !== input.role) return false;
|
|
5924
|
+
if (input.pinnedVariantId !== void 0 && item.pinned_variant_id !== input.pinnedVariantId) return false;
|
|
5925
|
+
if (input.sortIndex !== void 0 && item.sort_index !== input.sortIndex) return false;
|
|
5926
|
+
return true;
|
|
5927
|
+
}
|
|
5948
5928
|
var WebSocketClient = class WebSocketClient {
|
|
5949
5929
|
ws = null;
|
|
5950
5930
|
baseUrl;
|
|
@@ -6248,9 +6228,9 @@ var WebSocketClient = class WebSocketClient {
|
|
|
6248
6228
|
case "error": {
|
|
6249
6229
|
const errorMsg = message;
|
|
6250
6230
|
const error = /* @__PURE__ */ new Error(`${errorMsg.code}: ${errorMsg.message}`);
|
|
6251
|
-
const
|
|
6252
|
-
const
|
|
6253
|
-
if (!
|
|
6231
|
+
const requestConsumed = errorMsg.requestId ? this.failRequestHandler(errorMsg.requestId, error) : false;
|
|
6232
|
+
const mutationConsumed = requestConsumed ? false : this.failMutationWaiters(error);
|
|
6233
|
+
if (!requestConsumed && !mutationConsumed) {
|
|
6254
6234
|
console.error(`Server error: ${formatServerErrorMessage(errorMsg.code, errorMsg.message)}`);
|
|
6255
6235
|
this.onError?.(new Error(errorMsg.message));
|
|
6256
6236
|
}
|
|
@@ -6315,14 +6295,36 @@ var WebSocketClient = class WebSocketClient {
|
|
|
6315
6295
|
}
|
|
6316
6296
|
return true;
|
|
6317
6297
|
}
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
clearTimeout(handler.timeout);
|
|
6298
|
+
failRequestHandler(requestId, error) {
|
|
6299
|
+
const estimateHandler = this.estimateHandlers.get(requestId);
|
|
6300
|
+
if (estimateHandler) {
|
|
6322
6301
|
this.estimateHandlers.delete(requestId);
|
|
6302
|
+
clearTimeout(estimateHandler.timeout);
|
|
6303
|
+
estimateHandler.reject(error);
|
|
6304
|
+
return true;
|
|
6305
|
+
}
|
|
6306
|
+
const generateHandler = this.generateHandlers.get(requestId);
|
|
6307
|
+
if (generateHandler) {
|
|
6308
|
+
this.generateHandlers.delete(requestId);
|
|
6309
|
+
clearTimeout(generateHandler.timeout);
|
|
6310
|
+
generateHandler.reject(error);
|
|
6311
|
+
return true;
|
|
6312
|
+
}
|
|
6313
|
+
const batchHandler = this.batchHandlers.get(requestId);
|
|
6314
|
+
if (batchHandler) {
|
|
6315
|
+
this.batchHandlers.delete(requestId);
|
|
6316
|
+
clearTimeout(batchHandler.timeout);
|
|
6317
|
+
for (const variantId of batchHandler.pending) this.batchVariantToRequestId.delete(variantId);
|
|
6318
|
+
batchHandler.reject(error);
|
|
6319
|
+
return true;
|
|
6320
|
+
}
|
|
6321
|
+
for (const [variantId, handler] of this.variantCompletionHandlers) if (handler.requestId === requestId) {
|
|
6322
|
+
this.variantCompletionHandlers.delete(variantId);
|
|
6323
|
+
clearTimeout(handler.timeout);
|
|
6323
6324
|
handler.reject(error);
|
|
6325
|
+
return true;
|
|
6324
6326
|
}
|
|
6325
|
-
return
|
|
6327
|
+
return false;
|
|
6326
6328
|
}
|
|
6327
6329
|
/**
|
|
6328
6330
|
* Send a mutation message and resolve when a matching broadcast arrives, or
|
|
@@ -6407,6 +6409,42 @@ var WebSocketClient = class WebSocketClient {
|
|
|
6407
6409
|
rating
|
|
6408
6410
|
}, (msg) => msg.type === "variant:updated" && msg.variant.id === variantId && msg.variant.quality_rating === rating)).variant;
|
|
6409
6411
|
}
|
|
6412
|
+
async createCollection(input) {
|
|
6413
|
+
const id = input.id ?? crypto.randomUUID();
|
|
6414
|
+
return (await this.awaitServerMessage({
|
|
6415
|
+
type: "collection:create",
|
|
6416
|
+
...input,
|
|
6417
|
+
id
|
|
6418
|
+
}, (msg) => msg.type === "collection:created" && msg.collection.id === id)).collection;
|
|
6419
|
+
}
|
|
6420
|
+
async deleteCollection(collectionId) {
|
|
6421
|
+
await this.awaitServerMessage({
|
|
6422
|
+
type: "collection:delete",
|
|
6423
|
+
collectionId
|
|
6424
|
+
}, (msg) => msg.type === "collection:deleted" && msg.collectionId === collectionId);
|
|
6425
|
+
}
|
|
6426
|
+
async createCollectionItem(input) {
|
|
6427
|
+
const id = input.id ?? crypto.randomUUID();
|
|
6428
|
+
return (await this.awaitServerMessage({
|
|
6429
|
+
type: "collection_item:create",
|
|
6430
|
+
...input,
|
|
6431
|
+
id
|
|
6432
|
+
}, (msg) => msg.type === "collection_item:created" && msg.item.collection_id === input.collectionId && msg.item.id === id && collectionItemMatchesInput(msg.item, input))).item;
|
|
6433
|
+
}
|
|
6434
|
+
async deleteCollectionItem(collectionId, itemId) {
|
|
6435
|
+
await this.awaitServerMessage({
|
|
6436
|
+
type: "collection_item:delete",
|
|
6437
|
+
collectionId,
|
|
6438
|
+
itemId
|
|
6439
|
+
}, (msg) => msg.type === "collection_item:deleted" && msg.collectionId === collectionId && msg.itemId === itemId);
|
|
6440
|
+
}
|
|
6441
|
+
async reorderCollectionItems(collectionId, itemIds) {
|
|
6442
|
+
return (await this.awaitServerMessage({
|
|
6443
|
+
type: "collection_items:reorder",
|
|
6444
|
+
collectionId,
|
|
6445
|
+
itemIds
|
|
6446
|
+
}, (msg) => msg.type === "collection_items:reordered" && msg.collectionId === collectionId && itemIds.every((itemId, index) => msg.items[index]?.id === itemId))).items;
|
|
6447
|
+
}
|
|
6410
6448
|
/**
|
|
6411
6449
|
* Send a message through the WebSocket
|
|
6412
6450
|
*/
|
|
@@ -6990,7 +7028,7 @@ var MEDIA_OPERATION_MATRIX = [
|
|
|
6990
7028
|
assetType: "speech",
|
|
6991
7029
|
promptNoun: "speech clip",
|
|
6992
7030
|
inheritsReferenceAssetType: false,
|
|
6993
|
-
compatibleSlotMediaKinds: [
|
|
7031
|
+
compatibleSlotMediaKinds: [],
|
|
6994
7032
|
supportsBatch: true,
|
|
6995
7033
|
cliNamespace: "audio",
|
|
6996
7034
|
cliCommands: ["generate", "batch"],
|
|
@@ -7005,7 +7043,7 @@ var MEDIA_OPERATION_MATRIX = [
|
|
|
7005
7043
|
assetType: "dialogue",
|
|
7006
7044
|
promptNoun: "dialogue clip",
|
|
7007
7045
|
inheritsReferenceAssetType: false,
|
|
7008
|
-
compatibleSlotMediaKinds: [
|
|
7046
|
+
compatibleSlotMediaKinds: [],
|
|
7009
7047
|
supportsBatch: true,
|
|
7010
7048
|
cliNamespace: "audio",
|
|
7011
7049
|
cliCommands: ["generate", "batch"],
|
|
@@ -7020,7 +7058,7 @@ var MEDIA_OPERATION_MATRIX = [
|
|
|
7020
7058
|
assetType: "music",
|
|
7021
7059
|
promptNoun: "music cue",
|
|
7022
7060
|
inheritsReferenceAssetType: false,
|
|
7023
|
-
compatibleSlotMediaKinds: [
|
|
7061
|
+
compatibleSlotMediaKinds: [],
|
|
7024
7062
|
supportsBatch: true,
|
|
7025
7063
|
cliNamespace: "audio",
|
|
7026
7064
|
cliCommands: ["generate", "batch"],
|
|
@@ -7035,7 +7073,7 @@ var MEDIA_OPERATION_MATRIX = [
|
|
|
7035
7073
|
assetType: "sfx",
|
|
7036
7074
|
promptNoun: "sound effect",
|
|
7037
7075
|
inheritsReferenceAssetType: false,
|
|
7038
|
-
compatibleSlotMediaKinds: [
|
|
7076
|
+
compatibleSlotMediaKinds: [],
|
|
7039
7077
|
supportsBatch: true,
|
|
7040
7078
|
cliNamespace: "audio",
|
|
7041
7079
|
cliCommands: ["generate", "batch"],
|
|
@@ -7101,7 +7139,7 @@ function cliGenerationSupportsRefs(namespace) {
|
|
|
7101
7139
|
//#endregion
|
|
7102
7140
|
//#region src/cli/commands/forge.ts
|
|
7103
7141
|
var CLI_GENERATION_MEDIA_KIND = getCliGenerationMediaKind("top-level");
|
|
7104
|
-
var defaultDeps$
|
|
7142
|
+
var defaultDeps$8 = {
|
|
7105
7143
|
loadConfig: loadStoredConfig,
|
|
7106
7144
|
loadProjectConfig,
|
|
7107
7145
|
resolveBaseUrl,
|
|
@@ -7175,10 +7213,10 @@ async function handleBatch(parsed) {
|
|
|
7175
7213
|
}
|
|
7176
7214
|
async function handleForgeCommand(command, parsed) {
|
|
7177
7215
|
try {
|
|
7178
|
-
await executeForgeCommand(command, parsed, defaultDeps$
|
|
7216
|
+
await executeForgeCommand(command, parsed, defaultDeps$8);
|
|
7179
7217
|
} catch (error) {
|
|
7180
7218
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
7181
|
-
if (shouldPrintUsageForForgeError(error)) printUsage$
|
|
7219
|
+
if (shouldPrintUsageForForgeError(error)) printUsage$8(command);
|
|
7182
7220
|
process$1.exitCode = 1;
|
|
7183
7221
|
}
|
|
7184
7222
|
}
|
|
@@ -7187,11 +7225,11 @@ function shouldPrintUsageForForgeError(error) {
|
|
|
7187
7225
|
const message = error.message;
|
|
7188
7226
|
return message.startsWith("--") || message.startsWith("Output path is required") || message.startsWith("Output directory is required") || message.startsWith("Pass either prompt text") || message.startsWith("Speech generation requires") || message.startsWith("Dialogue generation requires") || message.startsWith("Prompt is required");
|
|
7189
7227
|
}
|
|
7190
|
-
async function executeForgeCommand(command, parsed, deps = defaultDeps$
|
|
7228
|
+
async function executeForgeCommand(command, parsed, deps = defaultDeps$8, options = {}) {
|
|
7191
7229
|
const mediaKind = options.mediaKind || CLI_GENERATION_MEDIA_KIND;
|
|
7192
7230
|
if (parsed.options.follow) {
|
|
7193
7231
|
if (command === "batch") throw new Error("--follow is only supported for single-output generation commands");
|
|
7194
|
-
const ctx = await buildContext$
|
|
7232
|
+
const ctx = await buildContext$5(parsed, deps);
|
|
7195
7233
|
const client = await deps.createClient(ctx.env, ctx.spaceId);
|
|
7196
7234
|
try {
|
|
7197
7235
|
await client.connect();
|
|
@@ -7205,7 +7243,7 @@ async function executeForgeCommand(command, parsed, deps = defaultDeps$7, option
|
|
|
7205
7243
|
validateVideoAudioOptions(parsed, mediaKind);
|
|
7206
7244
|
parseVideoGenerationOptions(parsed, mediaKind);
|
|
7207
7245
|
validateVideoFrameReferenceOptions(command, parsed, mediaKind);
|
|
7208
|
-
const ctx = await buildContext$
|
|
7246
|
+
const ctx = await buildContext$5(parsed, deps);
|
|
7209
7247
|
const client = await deps.createClient(ctx.env, ctx.spaceId);
|
|
7210
7248
|
try {
|
|
7211
7249
|
await client.connect();
|
|
@@ -7219,7 +7257,7 @@ async function executeForgeCommand(command, parsed, deps = defaultDeps$7, option
|
|
|
7219
7257
|
client.disconnect();
|
|
7220
7258
|
}
|
|
7221
7259
|
}
|
|
7222
|
-
async function executeAudioCommand(command, parsed, deps = defaultDeps$
|
|
7260
|
+
async function executeAudioCommand(command, parsed, deps = defaultDeps$8, options = {}) {
|
|
7223
7261
|
const audioProfile = getCliGenerationProfile("audio");
|
|
7224
7262
|
if (!audioProfile.commands.includes(command)) throw new Error(`Audio generation does not support ${command}`);
|
|
7225
7263
|
const modeEntry = options.mode ? getMediaOperationEntry(options.mode) : void 0;
|
|
@@ -7232,7 +7270,7 @@ async function executeAudioCommand(command, parsed, deps = defaultDeps$7, option
|
|
|
7232
7270
|
audioMode: options.mode
|
|
7233
7271
|
});
|
|
7234
7272
|
}
|
|
7235
|
-
async function executeVideoCommand(command, parsed, deps = defaultDeps$
|
|
7273
|
+
async function executeVideoCommand(command, parsed, deps = defaultDeps$8) {
|
|
7236
7274
|
const videoProfile = getCliGenerationProfile("video");
|
|
7237
7275
|
if (!videoProfile.commands.includes(command)) throw new Error(`Video generation does not support ${command}`);
|
|
7238
7276
|
return executeForgeCommand(command, parsed, deps, {
|
|
@@ -7271,12 +7309,17 @@ async function executeGenerate(parsed, ctx, client, deps, mediaKind, followOptio
|
|
|
7271
7309
|
const musicProvider = parseMusicProviderOption(parsed, mediaKind, assetType);
|
|
7272
7310
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7273
7311
|
const videoFrameRefs = parseVideoFrameReferenceOptions(parsed, "generate", mediaKind).refs;
|
|
7274
|
-
const state = videoFrameRefs.length > 0 ? await requestSpaceState(client) : void 0;
|
|
7312
|
+
const state = videoFrameRefs.length > 0 ? await requestSpaceState$1(client) : void 0;
|
|
7275
7313
|
const referenceVariantIds = videoFrameRefs.length > 0 ? await resolveReferenceVariantIds(videoFrameRefs, ctx, deps, state?.variants, CLI_GENERATION_MEDIA_KIND) : [];
|
|
7276
7314
|
const imageOptions = parseImageGenerationOptions(parsed, mediaKind);
|
|
7277
7315
|
const audioModelOptions = parseAudioGenerationOptions(parsed, mediaKind);
|
|
7278
7316
|
const videoAudioOptions = parseVideoAudioOptions(parsed, mediaKind);
|
|
7279
7317
|
const videoOptions = parseVideoGenerationOptions(parsed, mediaKind);
|
|
7318
|
+
const collectionPlacement = parseCollectionPlacementOptions(parsed);
|
|
7319
|
+
const followCommandOptions = {
|
|
7320
|
+
...followOptions,
|
|
7321
|
+
...collectionPlacement
|
|
7322
|
+
};
|
|
7280
7323
|
await printPreflightEstimate(client, {
|
|
7281
7324
|
operation: "generate",
|
|
7282
7325
|
assetType,
|
|
@@ -7309,7 +7352,7 @@ async function executeGenerate(parsed, ctx, client, deps, mediaKind, followOptio
|
|
|
7309
7352
|
...videoOptions,
|
|
7310
7353
|
onStarted: (started) => {
|
|
7311
7354
|
startedVariantId = started.jobId;
|
|
7312
|
-
printFollowHint(started, ctx, outputPath, "generate", mediaKind,
|
|
7355
|
+
printFollowHint(started, ctx, outputPath, "generate", mediaKind, followCommandOptions);
|
|
7313
7356
|
}
|
|
7314
7357
|
});
|
|
7315
7358
|
} catch (error) {
|
|
@@ -7319,7 +7362,7 @@ async function executeGenerate(parsed, ctx, client, deps, mediaKind, followOptio
|
|
|
7319
7362
|
ctx,
|
|
7320
7363
|
command: "generate",
|
|
7321
7364
|
mediaKind,
|
|
7322
|
-
followOptions
|
|
7365
|
+
followOptions: followCommandOptions
|
|
7323
7366
|
});
|
|
7324
7367
|
}
|
|
7325
7368
|
const manifestPath = await saveGenerationManifest({
|
|
@@ -7336,6 +7379,7 @@ async function executeGenerate(parsed, ctx, client, deps, mediaKind, followOptio
|
|
|
7336
7379
|
refs: videoFrameRefs,
|
|
7337
7380
|
referenceVariantIds
|
|
7338
7381
|
});
|
|
7382
|
+
await placeGeneratedAssetInCollection(result, ctx, deps, collectionPlacement);
|
|
7339
7383
|
await downloadResult(result, outputPath, ctx, deps);
|
|
7340
7384
|
printResult(result, outputPath, ctx, manifestPath);
|
|
7341
7385
|
return result;
|
|
@@ -7363,7 +7407,7 @@ async function executeRefine(parsed, ctx, client, deps, mediaKind) {
|
|
|
7363
7407
|
const prompt = getPrompt(parsed, "refine");
|
|
7364
7408
|
const outputPath = getOutputPath$1(parsed);
|
|
7365
7409
|
const sourceVariantId = requireOption$1(parsed, "variant");
|
|
7366
|
-
const state = await requestSpaceState(client);
|
|
7410
|
+
const state = await requestSpaceState$1(client);
|
|
7367
7411
|
const sourceVariant = state.variants.find((variant) => variant.id === sourceVariantId);
|
|
7368
7412
|
if (!sourceVariant) throw new Error(`Variant not found in space sync state: ${sourceVariantId}`);
|
|
7369
7413
|
const sourceAsset = state.assets.find((asset) => asset.id === sourceVariant.asset_id);
|
|
@@ -7371,6 +7415,8 @@ async function executeRefine(parsed, ctx, client, deps, mediaKind) {
|
|
|
7371
7415
|
const imageOptions = parseImageGenerationOptions(parsed, mediaKind);
|
|
7372
7416
|
const videoAudioOptions = parseVideoAudioOptions(parsed, mediaKind);
|
|
7373
7417
|
const videoOptions = parseVideoGenerationOptions(parsed, mediaKind);
|
|
7418
|
+
const collectionPlacement = parseCollectionPlacementOptions(parsed);
|
|
7419
|
+
const followCommandOptions = { ...collectionPlacement };
|
|
7374
7420
|
await printPreflightEstimate(client, {
|
|
7375
7421
|
operation: "refine",
|
|
7376
7422
|
assetId: sourceVariant.asset_id,
|
|
@@ -7398,7 +7444,7 @@ async function executeRefine(parsed, ctx, client, deps, mediaKind) {
|
|
|
7398
7444
|
...videoOptions,
|
|
7399
7445
|
onStarted: (started) => {
|
|
7400
7446
|
startedVariantId = started.jobId;
|
|
7401
|
-
printFollowHint(started, ctx, outputPath, "refine", mediaKind);
|
|
7447
|
+
printFollowHint(started, ctx, outputPath, "refine", mediaKind, followCommandOptions);
|
|
7402
7448
|
}
|
|
7403
7449
|
});
|
|
7404
7450
|
} catch (error) {
|
|
@@ -7407,7 +7453,8 @@ async function executeRefine(parsed, ctx, client, deps, mediaKind) {
|
|
|
7407
7453
|
outputPath,
|
|
7408
7454
|
ctx,
|
|
7409
7455
|
command: "refine",
|
|
7410
|
-
mediaKind
|
|
7456
|
+
mediaKind,
|
|
7457
|
+
followOptions: followCommandOptions
|
|
7411
7458
|
});
|
|
7412
7459
|
}
|
|
7413
7460
|
const manifestPath = await saveGenerationManifest({
|
|
@@ -7424,6 +7471,7 @@ async function executeRefine(parsed, ctx, client, deps, mediaKind) {
|
|
|
7424
7471
|
refs: [sourceVariantId],
|
|
7425
7472
|
referenceVariantIds: [sourceVariantId]
|
|
7426
7473
|
});
|
|
7474
|
+
await placeGeneratedAssetInCollection(result, ctx, deps, collectionPlacement);
|
|
7427
7475
|
await downloadResult(result, outputPath, ctx, deps);
|
|
7428
7476
|
printResult(result, outputPath, ctx, manifestPath);
|
|
7429
7477
|
return result;
|
|
@@ -7439,10 +7487,15 @@ async function executeDerive(parsed, ctx, client, deps, mediaKind, followOptions
|
|
|
7439
7487
|
if (referenceRefs.length === 0) throw new Error("--refs is required");
|
|
7440
7488
|
const imageOptions = parseImageGenerationOptions(parsed, mediaKind);
|
|
7441
7489
|
if (mediaKind === "image") validateImageReferenceCount(imageOptions.model, referenceRefs.length);
|
|
7442
|
-
const referenceVariantIds = await resolveReferenceVariantIds(referenceRefs, ctx, deps, (await requestSpaceState(client)).variants, videoFrameRefs.length > 0 ? CLI_GENERATION_MEDIA_KIND : mediaKind);
|
|
7490
|
+
const referenceVariantIds = await resolveReferenceVariantIds(referenceRefs, ctx, deps, (await requestSpaceState$1(client)).variants, videoFrameRefs.length > 0 ? CLI_GENERATION_MEDIA_KIND : mediaKind);
|
|
7443
7491
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7444
7492
|
const videoAudioOptions = parseVideoAudioOptions(parsed, mediaKind);
|
|
7445
7493
|
const videoOptions = parseVideoGenerationOptions(parsed, mediaKind);
|
|
7494
|
+
const collectionPlacement = parseCollectionPlacementOptions(parsed);
|
|
7495
|
+
const followCommandOptions = {
|
|
7496
|
+
...followOptions,
|
|
7497
|
+
...collectionPlacement
|
|
7498
|
+
};
|
|
7446
7499
|
await printPreflightEstimate(client, {
|
|
7447
7500
|
operation: "derive",
|
|
7448
7501
|
assetType,
|
|
@@ -7470,7 +7523,7 @@ async function executeDerive(parsed, ctx, client, deps, mediaKind, followOptions
|
|
|
7470
7523
|
...videoOptions,
|
|
7471
7524
|
onStarted: (started) => {
|
|
7472
7525
|
startedVariantId = started.jobId;
|
|
7473
|
-
printFollowHint(started, ctx, outputPath, "derive", mediaKind,
|
|
7526
|
+
printFollowHint(started, ctx, outputPath, "derive", mediaKind, followCommandOptions);
|
|
7474
7527
|
}
|
|
7475
7528
|
});
|
|
7476
7529
|
} catch (error) {
|
|
@@ -7480,7 +7533,7 @@ async function executeDerive(parsed, ctx, client, deps, mediaKind, followOptions
|
|
|
7480
7533
|
ctx,
|
|
7481
7534
|
command: "derive",
|
|
7482
7535
|
mediaKind,
|
|
7483
|
-
followOptions
|
|
7536
|
+
followOptions: followCommandOptions
|
|
7484
7537
|
});
|
|
7485
7538
|
}
|
|
7486
7539
|
const manifestPath = await saveGenerationManifest({
|
|
@@ -7497,6 +7550,7 @@ async function executeDerive(parsed, ctx, client, deps, mediaKind, followOptions
|
|
|
7497
7550
|
refs: referenceRefs,
|
|
7498
7551
|
referenceVariantIds
|
|
7499
7552
|
});
|
|
7553
|
+
await placeGeneratedAssetInCollection(result, ctx, deps, collectionPlacement);
|
|
7500
7554
|
await downloadResult(result, outputPath, ctx, deps);
|
|
7501
7555
|
printResult(result, outputPath, ctx, manifestPath);
|
|
7502
7556
|
return result;
|
|
@@ -7506,8 +7560,13 @@ async function executeFollow(parsed, ctx, client, deps, command, mediaKind, foll
|
|
|
7506
7560
|
if (!variantId) throw new Error("--follow requires a variant ID");
|
|
7507
7561
|
const outputPath = getOutputPath$1(parsed);
|
|
7508
7562
|
const timeoutMs = parseFollowTimeoutMs(parsed, mediaKind);
|
|
7563
|
+
const collectionPlacement = parseCollectionPlacementOptions(parsed);
|
|
7564
|
+
const followCommandOptions = {
|
|
7565
|
+
...followOptions,
|
|
7566
|
+
...collectionPlacement
|
|
7567
|
+
};
|
|
7509
7568
|
console.log(`Following variant ${variantId} in space ${ctx.spaceId}...`);
|
|
7510
|
-
const state = await requestSpaceState(client);
|
|
7569
|
+
const state = await requestSpaceState$1(client);
|
|
7511
7570
|
const initialVariant = state.variants.find((variant) => variant.id === variantId);
|
|
7512
7571
|
if (!initialVariant) throw new Error(`Variant not found in space sync state: ${variantId}`);
|
|
7513
7572
|
const initialStatus = initialVariant.status;
|
|
@@ -7527,7 +7586,7 @@ async function executeFollow(parsed, ctx, client, deps, command, mediaKind, foll
|
|
|
7527
7586
|
}
|
|
7528
7587
|
}
|
|
7529
7588
|
});
|
|
7530
|
-
const refreshedVariant = (await requestSpaceState(client)).variants.find((variant) => variant.id === variantId);
|
|
7589
|
+
const refreshedVariant = (await requestSpaceState$1(client)).variants.find((variant) => variant.id === variantId);
|
|
7531
7590
|
result = refreshedVariant ? resultFromTerminalVariant(refreshedVariant, requestId) : void 0;
|
|
7532
7591
|
if (result) client.cancelFollowVariant?.(variantId, requestId);
|
|
7533
7592
|
else try {
|
|
@@ -7539,7 +7598,7 @@ async function executeFollow(parsed, ctx, client, deps, command, mediaKind, foll
|
|
|
7539
7598
|
ctx,
|
|
7540
7599
|
command,
|
|
7541
7600
|
mediaKind,
|
|
7542
|
-
followOptions
|
|
7601
|
+
followOptions: followCommandOptions
|
|
7543
7602
|
});
|
|
7544
7603
|
}
|
|
7545
7604
|
}
|
|
@@ -7562,6 +7621,7 @@ async function executeFollow(parsed, ctx, client, deps, command, mediaKind, foll
|
|
|
7562
7621
|
referenceVariantIds
|
|
7563
7622
|
});
|
|
7564
7623
|
await downloadResult(result, outputPath, ctx, deps);
|
|
7624
|
+
await placeGeneratedAssetInCollection(result, ctx, deps, collectionPlacement);
|
|
7565
7625
|
printResult(result, outputPath, ctx, manifestPath);
|
|
7566
7626
|
return result;
|
|
7567
7627
|
}
|
|
@@ -7654,10 +7714,11 @@ async function executeBatch(parsed, ctx, client, deps, mediaKind, saveBatchManif
|
|
|
7654
7714
|
const imageOptions = parseImageGenerationOptions(parsed, mediaKind);
|
|
7655
7715
|
const audioModelOptions = parseAudioGenerationOptions(parsed, mediaKind);
|
|
7656
7716
|
if (mediaKind === "image") validateImageReferenceCount(imageOptions.model, refs.length);
|
|
7657
|
-
const state = await requestSpaceState(client);
|
|
7717
|
+
const state = await requestSpaceState$1(client);
|
|
7658
7718
|
const referenceVariantIds = refs.length > 0 ? await resolveReferenceVariantIds(refs, ctx, deps, state.variants, mediaKind) : void 0;
|
|
7659
7719
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7660
7720
|
const runId = deps.createRunId();
|
|
7721
|
+
const collectionPlacement = parseCollectionPlacementOptions(parsed);
|
|
7661
7722
|
await printPreflightEstimate(client, {
|
|
7662
7723
|
operation: "batch",
|
|
7663
7724
|
assetType,
|
|
@@ -7696,6 +7757,7 @@ async function executeBatch(parsed, ctx, client, deps, mediaKind, saveBatchManif
|
|
|
7696
7757
|
}
|
|
7697
7758
|
const sortedVariants = [...result.variants].sort((a, b) => a.created_at - b.created_at);
|
|
7698
7759
|
const media = [];
|
|
7760
|
+
await placeGeneratedBatchAssetsInCollection(result, ctx, deps, collectionPlacement);
|
|
7699
7761
|
for (let index = 0; index < sortedVariants.length; index += 1) {
|
|
7700
7762
|
const variant = sortedVariants[index];
|
|
7701
7763
|
const outputPath = path.join(outputDir, `${slugify(name)}-${String(index + 1).padStart(2, "0")}.${getOutputExtension(variant, mediaKind)}`);
|
|
@@ -7781,7 +7843,69 @@ async function saveGenerationManifest(input) {
|
|
|
7781
7843
|
failed: []
|
|
7782
7844
|
}, ctx.projectRoot);
|
|
7783
7845
|
}
|
|
7784
|
-
|
|
7846
|
+
function parseCollectionPlacementOptions(parsed) {
|
|
7847
|
+
const collectionId = normalizeCliOption(readOptionalOption(parsed, "collection", "collection") ?? readOptionalOption(parsed, "collection-id", "collectionId"));
|
|
7848
|
+
if (parsed.options.collection !== void 0 || parsed.options.collectionId !== void 0 || parsed.options["collection-id"] !== void 0) {
|
|
7849
|
+
if (!collectionId) throw new Error("--collection requires a collection ID");
|
|
7850
|
+
}
|
|
7851
|
+
return collectionId ? { collectionId } : {};
|
|
7852
|
+
}
|
|
7853
|
+
async function placeGeneratedAssetInCollection(result, ctx, deps, options) {
|
|
7854
|
+
if (!options.collectionId || !result.success || !result.variant) return;
|
|
7855
|
+
await createCollectionAssetItem({
|
|
7856
|
+
ctx,
|
|
7857
|
+
deps,
|
|
7858
|
+
collectionId: options.collectionId,
|
|
7859
|
+
assetId: result.variant.asset_id,
|
|
7860
|
+
pinnedVariantId: result.variant.id
|
|
7861
|
+
});
|
|
7862
|
+
}
|
|
7863
|
+
async function placeGeneratedBatchAssetsInCollection(result, ctx, deps, options) {
|
|
7864
|
+
if (!options.collectionId || !result.success) return;
|
|
7865
|
+
const firstVariantByAsset = /* @__PURE__ */ new Map();
|
|
7866
|
+
for (const variant of [...result.variants].sort((a, b) => a.created_at - b.created_at)) if (!firstVariantByAsset.has(variant.asset_id)) firstVariantByAsset.set(variant.asset_id, variant);
|
|
7867
|
+
for (const variant of firstVariantByAsset.values()) await createCollectionAssetItem({
|
|
7868
|
+
ctx,
|
|
7869
|
+
deps,
|
|
7870
|
+
collectionId: options.collectionId,
|
|
7871
|
+
assetId: variant.asset_id,
|
|
7872
|
+
pinnedVariantId: variant.id
|
|
7873
|
+
});
|
|
7874
|
+
}
|
|
7875
|
+
async function createCollectionAssetItem(input) {
|
|
7876
|
+
const fetchImpl = input.deps.fetch ?? fetch;
|
|
7877
|
+
const itemsUrl = `${input.ctx.baseUrl}/api/spaces/${encodeURIComponent(input.ctx.spaceId)}/collections/${encodeURIComponent(input.collectionId)}/items`;
|
|
7878
|
+
const listResponse = await fetchImpl(itemsUrl, { headers: {
|
|
7879
|
+
"Authorization": `Bearer ${input.ctx.accessToken}`,
|
|
7880
|
+
"Accept": "application/json"
|
|
7881
|
+
} });
|
|
7882
|
+
if (!listResponse.ok) {
|
|
7883
|
+
const errorText = await listResponse.text();
|
|
7884
|
+
throw new Error(`Failed to inspect collection ${input.collectionId} (${listResponse.status}): ${errorText || listResponse.statusText}`);
|
|
7885
|
+
}
|
|
7886
|
+
const existing = await listResponse.json();
|
|
7887
|
+
if (existing.items?.some((item) => item.asset_id === input.assetId)) return;
|
|
7888
|
+
const sortIndex = Math.max(-1, ...(existing.items ?? []).map((item) => typeof item.sort_index === "number" && Number.isFinite(item.sort_index) ? item.sort_index : -1)) + 1;
|
|
7889
|
+
const response = await fetchImpl(itemsUrl, {
|
|
7890
|
+
method: "POST",
|
|
7891
|
+
headers: {
|
|
7892
|
+
"Authorization": `Bearer ${input.ctx.accessToken}`,
|
|
7893
|
+
"Content-Type": "application/json",
|
|
7894
|
+
"Accept": "application/json"
|
|
7895
|
+
},
|
|
7896
|
+
body: JSON.stringify({
|
|
7897
|
+
subjectType: "asset",
|
|
7898
|
+
assetId: input.assetId,
|
|
7899
|
+
pinnedVariantId: input.pinnedVariantId,
|
|
7900
|
+
sortIndex
|
|
7901
|
+
})
|
|
7902
|
+
});
|
|
7903
|
+
if (!response.ok) {
|
|
7904
|
+
const errorText = await response.text();
|
|
7905
|
+
throw new Error(`Failed to place asset ${input.assetId} in collection ${input.collectionId} (${response.status}): ${errorText || response.statusText}`);
|
|
7906
|
+
}
|
|
7907
|
+
}
|
|
7908
|
+
async function buildContext$5(parsed, deps) {
|
|
7785
7909
|
const projectConfig = await deps.loadProjectConfig();
|
|
7786
7910
|
const env = resolveCommandEnvironment(parsed, projectConfig);
|
|
7787
7911
|
const spaceId = resolveCommandSpace(parsed, projectConfig);
|
|
@@ -7898,7 +8022,7 @@ function validateReferenceVariant(ref, variants, mediaKind) {
|
|
|
7898
8022
|
if (!variant.image_key && !variant.media_key) throw new Error(`Reference variant has no image or video media: ${ref}`);
|
|
7899
8023
|
}
|
|
7900
8024
|
}
|
|
7901
|
-
function requestSpaceState(client) {
|
|
8025
|
+
function requestSpaceState$1(client) {
|
|
7902
8026
|
return new Promise((resolve, reject) => {
|
|
7903
8027
|
const timer = setTimeout(() => {
|
|
7904
8028
|
reject(/* @__PURE__ */ new Error("Timed out waiting for space sync state"));
|
|
@@ -7951,12 +8075,13 @@ function printFollowHint(started, ctx, outputPath, command, mediaKind, options =
|
|
|
7951
8075
|
}
|
|
7952
8076
|
function throwGenerationWaitErrorIfNeeded(input, params) {
|
|
7953
8077
|
if (!isGenerationWaitTimeout(input)) throw input;
|
|
7954
|
-
if (!params.variantId) throw new Error(["Make Effects
|
|
8078
|
+
if (!params.variantId) throw new Error(["The CLI timed out before Make Effects returned a variant ID.", "The generation may still have started. Check the Space in the web app before retrying, so you do not create a duplicate."].join("\n"));
|
|
7955
8079
|
const followCommand = formatFollowCommand(params.variantId, params.outputPath, params.ctx, params.command, params.mediaKind, params.followOptions);
|
|
7956
8080
|
throw new Error([
|
|
7957
|
-
"
|
|
8081
|
+
"The CLI stopped waiting, but the Make Effects generation job is still running.",
|
|
8082
|
+
"Do not retry this generation unless you want a duplicate asset.",
|
|
7958
8083
|
"",
|
|
7959
|
-
"Resume the download
|
|
8084
|
+
"Resume the same job and download the variant when it is ready:",
|
|
7960
8085
|
` ${followCommand}`,
|
|
7961
8086
|
"",
|
|
7962
8087
|
`Variant: ${params.variantId}`
|
|
@@ -7964,7 +8089,7 @@ function throwGenerationWaitErrorIfNeeded(input, params) {
|
|
|
7964
8089
|
}
|
|
7965
8090
|
function throwBatchWaitErrorIfNeeded(input, started, ctx) {
|
|
7966
8091
|
if (!isBatchWaitTimeout(input)) throw input;
|
|
7967
|
-
if (!started) throw new Error(["Make Effects
|
|
8092
|
+
if (!started) throw new Error(["The CLI timed out before Make Effects returned batch variant IDs.", "The batch may still have started. Check the Space in the web app before retrying, so you do not create duplicate assets."].join("\n"));
|
|
7968
8093
|
const downloadExample = [
|
|
7969
8094
|
"makefx assets download <variant_id> -o <file>",
|
|
7970
8095
|
...ctx.env === "local" ? ["--local"] : ["--env", ctx.env],
|
|
@@ -7972,7 +8097,8 @@ function throwBatchWaitErrorIfNeeded(input, started, ctx) {
|
|
|
7972
8097
|
ctx.spaceId
|
|
7973
8098
|
].join(" ");
|
|
7974
8099
|
throw new Error([
|
|
7975
|
-
"
|
|
8100
|
+
"The CLI stopped waiting, but the Make Effects batch jobs are still running.",
|
|
8101
|
+
"Do not retry this batch unless you want duplicate assets.",
|
|
7976
8102
|
"",
|
|
7977
8103
|
`Started variants: ${started.jobIds.join(", ")}`,
|
|
7978
8104
|
"",
|
|
@@ -7999,6 +8125,7 @@ function formatFollowCommand(variantId, outputPath, ctx, command, mediaKind, opt
|
|
|
7999
8125
|
command
|
|
8000
8126
|
] : ["makefx", command];
|
|
8001
8127
|
const envArgs = ctx.env === "local" ? ["--local"] : ["--env", ctx.env];
|
|
8128
|
+
const collectionArgs = options.collectionId ? ["--collection", options.collectionId] : [];
|
|
8002
8129
|
return [
|
|
8003
8130
|
...baseCommand,
|
|
8004
8131
|
"--follow",
|
|
@@ -8007,7 +8134,8 @@ function formatFollowCommand(variantId, outputPath, ctx, command, mediaKind, opt
|
|
|
8007
8134
|
outputPath,
|
|
8008
8135
|
...envArgs,
|
|
8009
8136
|
"--space",
|
|
8010
|
-
ctx.spaceId
|
|
8137
|
+
ctx.spaceId,
|
|
8138
|
+
...collectionArgs
|
|
8011
8139
|
].map(shellQuote).join(" ");
|
|
8012
8140
|
}
|
|
8013
8141
|
function shellQuote(value) {
|
|
@@ -8250,34 +8378,34 @@ function cliImageSizeValues() {
|
|
|
8250
8378
|
function cliImageAspectValues() {
|
|
8251
8379
|
return cliOptionValues(getImageModelCapabilities().supportedAspectRatios);
|
|
8252
8380
|
}
|
|
8253
|
-
function printUsage$
|
|
8381
|
+
function printUsage$8(command) {
|
|
8254
8382
|
if (command === "generate") {
|
|
8255
8383
|
console.log(`
|
|
8256
8384
|
Usage:
|
|
8257
|
-
makefx generate "prompt" --name <name> --type <type> -o <file> [--model pro|flash] [--size ${cliImageSizeValues()}] [--aspect ${cliImageAspectValues()}] [--space <id>]
|
|
8258
|
-
makefx generate --follow <variant_id> -o <file> [--space <id>]
|
|
8385
|
+
makefx generate "prompt" --name <name> --type <type> -o <file> [--model pro|flash] [--size ${cliImageSizeValues()}] [--aspect ${cliImageAspectValues()}] [--collection <id>] [--space <id>]
|
|
8386
|
+
makefx generate --follow <variant_id> -o <file> [--collection <id>] [--space <id>]
|
|
8259
8387
|
`);
|
|
8260
8388
|
return;
|
|
8261
8389
|
}
|
|
8262
8390
|
if (command === "refine") {
|
|
8263
8391
|
console.log(`
|
|
8264
8392
|
Usage:
|
|
8265
|
-
makefx refine --variant <variant_id> "prompt" -o <file> [--model pro|flash] [--size ${cliImageSizeValues()}] [--aspect ${cliImageAspectValues()}] [--space <id>]
|
|
8266
|
-
makefx refine --follow <variant_id> -o <file> [--space <id>]
|
|
8393
|
+
makefx refine --variant <variant_id> "prompt" -o <file> [--model pro|flash] [--size ${cliImageSizeValues()}] [--aspect ${cliImageAspectValues()}] [--collection <id>] [--space <id>]
|
|
8394
|
+
makefx refine --follow <variant_id> -o <file> [--collection <id>] [--space <id>]
|
|
8267
8395
|
`);
|
|
8268
8396
|
return;
|
|
8269
8397
|
}
|
|
8270
8398
|
if (command === "batch") {
|
|
8271
8399
|
console.log(`
|
|
8272
8400
|
Usage:
|
|
8273
|
-
makefx batch "prompt" --name <name> --type <type> --count <2-8> --output-dir <dir> [--model pro|flash] [--size ${cliImageSizeValues()}] [--aspect ${cliImageAspectValues()}]
|
|
8401
|
+
makefx batch "prompt" --name <name> --type <type> --count <2-8> --output-dir <dir> [--model pro|flash] [--size ${cliImageSizeValues()}] [--aspect ${cliImageAspectValues()}] [--collection <id>]
|
|
8274
8402
|
`);
|
|
8275
8403
|
return;
|
|
8276
8404
|
}
|
|
8277
8405
|
console.log(`
|
|
8278
8406
|
Usage:
|
|
8279
|
-
makefx derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--model pro|flash] [--size ${cliImageSizeValues()}] [--aspect ${cliImageAspectValues()}] [--space <id>]
|
|
8280
|
-
makefx derive --follow <variant_id> -o <file> [--space <id>]
|
|
8407
|
+
makefx derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--model pro|flash] [--size ${cliImageSizeValues()}] [--aspect ${cliImageAspectValues()}] [--collection <id>] [--space <id>]
|
|
8408
|
+
makefx derive --follow <variant_id> -o <file> [--collection <id>] [--space <id>]
|
|
8281
8409
|
`);
|
|
8282
8410
|
}
|
|
8283
8411
|
function printBatchResult(result, outputDir, manifestPath, ctx, mediaKind) {
|
|
@@ -8291,7 +8419,7 @@ function printBatchResult(result, outputDir, manifestPath, ctx, mediaKind) {
|
|
|
8291
8419
|
}
|
|
8292
8420
|
//#endregion
|
|
8293
8421
|
//#region src/cli/commands/audio.ts
|
|
8294
|
-
var defaultDeps$
|
|
8422
|
+
var defaultDeps$7 = {
|
|
8295
8423
|
loadConfig: loadStoredConfig,
|
|
8296
8424
|
loadProjectConfig,
|
|
8297
8425
|
resolveBaseUrl,
|
|
@@ -8304,11 +8432,11 @@ async function handleAudio(parsed) {
|
|
|
8304
8432
|
await executeAudio(parsed);
|
|
8305
8433
|
} catch (error) {
|
|
8306
8434
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
8307
|
-
printUsage$
|
|
8435
|
+
printUsage$7();
|
|
8308
8436
|
process$1.exitCode = 1;
|
|
8309
8437
|
}
|
|
8310
8438
|
}
|
|
8311
|
-
async function executeAudio(parsed, deps = defaultDeps$
|
|
8439
|
+
async function executeAudio(parsed, deps = defaultDeps$7) {
|
|
8312
8440
|
const invocation = parseAudioInvocation(parsed.positionals);
|
|
8313
8441
|
if (invocation.command === "voices") return executeAudioVoices({
|
|
8314
8442
|
...parsed,
|
|
@@ -8381,7 +8509,7 @@ function printVoices(response, print) {
|
|
|
8381
8509
|
function formatLabels(labels) {
|
|
8382
8510
|
return Object.entries(labels).map(([key, value]) => `${key}:${value}`).join(", ");
|
|
8383
8511
|
}
|
|
8384
|
-
function printUsage$
|
|
8512
|
+
function printUsage$7() {
|
|
8385
8513
|
const modes = AUDIO_FORGE_MEDIA_MODES.join("|");
|
|
8386
8514
|
console.log(`
|
|
8387
8515
|
Usage:
|
|
@@ -8410,7 +8538,7 @@ async function handleVideo(parsed) {
|
|
|
8410
8538
|
});
|
|
8411
8539
|
} catch (error) {
|
|
8412
8540
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
8413
|
-
printUsage$
|
|
8541
|
+
printUsage$6();
|
|
8414
8542
|
process$1.exitCode = 1;
|
|
8415
8543
|
}
|
|
8416
8544
|
}
|
|
@@ -8419,7 +8547,7 @@ function parseVideoCommand(value) {
|
|
|
8419
8547
|
if (value && commands.includes(value)) return value;
|
|
8420
8548
|
throw new Error("Video command is required: generate, refine, or derive");
|
|
8421
8549
|
}
|
|
8422
|
-
function printUsage$
|
|
8550
|
+
function printUsage$6() {
|
|
8423
8551
|
const aspectValues = VIDEO_GENERATION_ASPECT_RATIOS.join("|");
|
|
8424
8552
|
const resolutionValues = Array.from(new Set(VIDEO_GENERATION_TIERS.flatMap((tier) => getVideoGenerationResolutionsForTier(tier)))).join("|");
|
|
8425
8553
|
const durationValues = VIDEO_GENERATION_DURATION_SECONDS.join("|");
|
|
@@ -8458,17 +8586,17 @@ Audio:
|
|
|
8458
8586
|
}
|
|
8459
8587
|
//#endregion
|
|
8460
8588
|
//#region src/cli/commands/init.ts
|
|
8461
|
-
var defaultDeps$
|
|
8589
|
+
var defaultDeps$6 = { saveProjectConfig };
|
|
8462
8590
|
async function handleInit(parsed) {
|
|
8463
8591
|
try {
|
|
8464
8592
|
await executeInit(parsed);
|
|
8465
8593
|
} catch (error) {
|
|
8466
8594
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
8467
|
-
printUsage$
|
|
8595
|
+
printUsage$5();
|
|
8468
8596
|
process$1.exitCode = 1;
|
|
8469
8597
|
}
|
|
8470
8598
|
}
|
|
8471
|
-
async function executeInit(parsed, deps = defaultDeps$
|
|
8599
|
+
async function executeInit(parsed, deps = defaultDeps$6) {
|
|
8472
8600
|
const environment = resolveCommandEnvironment(parsed);
|
|
8473
8601
|
const spaceId = resolveCommandSpace(parsed);
|
|
8474
8602
|
if (!spaceId) throw new Error("--space is required");
|
|
@@ -8494,7 +8622,7 @@ async function executeInit(parsed, deps = defaultDeps$5) {
|
|
|
8494
8622
|
spaceId
|
|
8495
8623
|
};
|
|
8496
8624
|
}
|
|
8497
|
-
function printUsage$
|
|
8625
|
+
function printUsage$5() {
|
|
8498
8626
|
console.log(`
|
|
8499
8627
|
Usage:
|
|
8500
8628
|
makefx init --space <id> [--env production|stage|local]
|
|
@@ -8503,7 +8631,7 @@ Usage:
|
|
|
8503
8631
|
}
|
|
8504
8632
|
//#endregion
|
|
8505
8633
|
//#region src/cli/commands/runs.ts
|
|
8506
|
-
var defaultDeps$
|
|
8634
|
+
var defaultDeps$5 = {
|
|
8507
8635
|
loadProjectConfig,
|
|
8508
8636
|
listRunManifests,
|
|
8509
8637
|
readRunManifest,
|
|
@@ -8516,11 +8644,11 @@ async function handleRuns(parsed) {
|
|
|
8516
8644
|
await executeRuns(parsed);
|
|
8517
8645
|
} catch (error) {
|
|
8518
8646
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
8519
|
-
printUsage$
|
|
8647
|
+
printUsage$4();
|
|
8520
8648
|
process$1.exitCode = 1;
|
|
8521
8649
|
}
|
|
8522
8650
|
}
|
|
8523
|
-
async function executeRuns(parsed, deps = defaultDeps$
|
|
8651
|
+
async function executeRuns(parsed, deps = defaultDeps$5) {
|
|
8524
8652
|
const projectConfig = await deps.loadProjectConfig();
|
|
8525
8653
|
if (!projectConfig?.projectRoot) throw new Error("Make Effects project config not found. Run: makefx init --space <id>");
|
|
8526
8654
|
requireDebugAcknowledgement(parsed);
|
|
@@ -8638,7 +8766,7 @@ function formatCreated(value) {
|
|
|
8638
8766
|
if (Number.isNaN(date.getTime())) return value;
|
|
8639
8767
|
return value.replace("T", " ").replace(/\.\d{3}Z$/, "Z").slice(0, 20);
|
|
8640
8768
|
}
|
|
8641
|
-
function printUsage$
|
|
8769
|
+
function printUsage$4() {
|
|
8642
8770
|
console.log(`
|
|
8643
8771
|
Usage:
|
|
8644
8772
|
makefx runs --debug
|
|
@@ -8653,7 +8781,7 @@ Local run manifests are debug-only artifacts, not a source of truth.
|
|
|
8653
8781
|
}
|
|
8654
8782
|
//#endregion
|
|
8655
8783
|
//#region src/cli/commands/assets.ts
|
|
8656
|
-
var defaultDeps$
|
|
8784
|
+
var defaultDeps$4 = {
|
|
8657
8785
|
loadConfig: loadStoredConfig,
|
|
8658
8786
|
loadProjectConfig,
|
|
8659
8787
|
resolveBaseUrl,
|
|
@@ -8677,15 +8805,15 @@ async function handleAssets(parsed) {
|
|
|
8677
8805
|
await executeAssets(parsed);
|
|
8678
8806
|
} catch (error) {
|
|
8679
8807
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
8680
|
-
printUsage$
|
|
8808
|
+
printUsage$3();
|
|
8681
8809
|
process$1.exitCode = 1;
|
|
8682
8810
|
}
|
|
8683
8811
|
}
|
|
8684
|
-
async function executeAssets(parsed, deps = defaultDeps$
|
|
8812
|
+
async function executeAssets(parsed, deps = defaultDeps$4) {
|
|
8685
8813
|
const subcommand = parsed.positionals[0] || "list";
|
|
8686
8814
|
if (subcommand === "search") return searchAssets(parsed, deps);
|
|
8687
8815
|
if (subcommand === "clone") return cloneAsset(parsed, deps);
|
|
8688
|
-
const ctx = await buildContext$
|
|
8816
|
+
const ctx = await buildContext$4(parsed, deps);
|
|
8689
8817
|
if (subcommand === "list") {
|
|
8690
8818
|
const assets = await listAssets(ctx, deps);
|
|
8691
8819
|
if (parsed.options.json === "true") deps.print(JSON.stringify(assets.map(toAssetJson), null, 2));
|
|
@@ -8711,13 +8839,21 @@ async function executeAssets(parsed, deps = defaultDeps$3) {
|
|
|
8711
8839
|
if (!ref) throw new Error("Variant ID or legacy image key is required: makefx assets download <variant-id-or-legacy-image-key> -o <file>");
|
|
8712
8840
|
const outputPath = getOutputPath(parsed);
|
|
8713
8841
|
const resolved = resolveDownloadRef(ref, ctx);
|
|
8714
|
-
|
|
8715
|
-
|
|
8716
|
-
|
|
8717
|
-
|
|
8718
|
-
|
|
8719
|
-
|
|
8720
|
-
|
|
8842
|
+
let download;
|
|
8843
|
+
try {
|
|
8844
|
+
download = await deps.downloadFile({
|
|
8845
|
+
baseUrl: ctx.baseUrl,
|
|
8846
|
+
accessToken: ctx.accessToken,
|
|
8847
|
+
requestPath: resolved.requestPath,
|
|
8848
|
+
outputPath,
|
|
8849
|
+
force: ctx.force
|
|
8850
|
+
});
|
|
8851
|
+
} catch (error) {
|
|
8852
|
+
const failedVariantMessage = await getFailedDownloadVariantMessage(error, resolved, ctx, deps);
|
|
8853
|
+
if (failedVariantMessage) throw new Error(failedVariantMessage);
|
|
8854
|
+
throw error;
|
|
8855
|
+
}
|
|
8856
|
+
const metadata = getDownloadedVariantMetadata(resolved, download);
|
|
8721
8857
|
await recordDownloadedMirror({
|
|
8722
8858
|
ctx,
|
|
8723
8859
|
deps,
|
|
@@ -8755,7 +8891,7 @@ async function executeAssets(parsed, deps = defaultDeps$3) {
|
|
|
8755
8891
|
}
|
|
8756
8892
|
if (subcommand === "set-active") {
|
|
8757
8893
|
const assetId = parsed.positionals[1];
|
|
8758
|
-
const variantId = parsed.positionals[2] || normalizeOption(parsed.options.variant);
|
|
8894
|
+
const variantId = parsed.positionals[2] || normalizeOption$1(parsed.options.variant);
|
|
8759
8895
|
if (!assetId || !variantId) throw new Error("Usage: makefx assets set-active <asset-id> <variant-id>");
|
|
8760
8896
|
const asset = await setActiveVariant(ctx, deps, assetId, variantId);
|
|
8761
8897
|
deps.print(`Set active variant of asset ${assetId} to ${asset.active_variant_id}`);
|
|
@@ -8766,10 +8902,10 @@ async function executeAssets(parsed, deps = defaultDeps$3) {
|
|
|
8766
8902
|
}
|
|
8767
8903
|
throw new Error(`Unknown assets command: ${subcommand}`);
|
|
8768
8904
|
}
|
|
8769
|
-
function normalizeOption(value) {
|
|
8905
|
+
function normalizeOption$1(value) {
|
|
8770
8906
|
return !value || value === "true" ? void 0 : value;
|
|
8771
8907
|
}
|
|
8772
|
-
async function buildContext$
|
|
8908
|
+
async function buildContext$4(parsed, deps) {
|
|
8773
8909
|
const projectConfig = await deps.loadProjectConfig();
|
|
8774
8910
|
const env = resolveCommandEnvironment(parsed, projectConfig);
|
|
8775
8911
|
const spaceId = resolveCommandSpace(parsed, projectConfig);
|
|
@@ -8801,7 +8937,7 @@ async function buildAuthContext(parsed, deps) {
|
|
|
8801
8937
|
}
|
|
8802
8938
|
function requireOption(parsed, names, usage) {
|
|
8803
8939
|
for (const name of names) {
|
|
8804
|
-
const value = normalizeOption(parsed.options[name]);
|
|
8940
|
+
const value = normalizeOption$1(parsed.options[name]);
|
|
8805
8941
|
if (value) return value;
|
|
8806
8942
|
}
|
|
8807
8943
|
throw new Error(usage);
|
|
@@ -8811,9 +8947,9 @@ async function searchAssets(parsed, deps) {
|
|
|
8811
8947
|
const query = parsed.positionals.slice(1).join(" ").trim();
|
|
8812
8948
|
const params = new URLSearchParams();
|
|
8813
8949
|
if (query) params.set("q", query);
|
|
8814
|
-
const mediaKind = normalizeOption(parsed.options.media) ?? normalizeOption(parsed.options["media-kind"]);
|
|
8815
|
-
const assetType = normalizeOption(parsed.options.type);
|
|
8816
|
-
const limit = normalizeOption(parsed.options.limit);
|
|
8950
|
+
const mediaKind = normalizeOption$1(parsed.options.media) ?? normalizeOption$1(parsed.options["media-kind"]);
|
|
8951
|
+
const assetType = normalizeOption$1(parsed.options.type);
|
|
8952
|
+
const limit = normalizeOption$1(parsed.options.limit);
|
|
8817
8953
|
if (mediaKind) params.set("media_kind", mediaKind);
|
|
8818
8954
|
if (assetType) params.set("type", assetType);
|
|
8819
8955
|
if (limit) params.set("limit", limit);
|
|
@@ -8829,7 +8965,7 @@ async function searchAssets(parsed, deps) {
|
|
|
8829
8965
|
}
|
|
8830
8966
|
async function cloneAsset(parsed, deps) {
|
|
8831
8967
|
const ctx = await buildAuthContext(parsed, deps);
|
|
8832
|
-
const sourceVariantId = parsed.positionals[1] ?? normalizeOption(parsed.options.variant);
|
|
8968
|
+
const sourceVariantId = parsed.positionals[1] ?? normalizeOption$1(parsed.options.variant);
|
|
8833
8969
|
if (!sourceVariantId) throw new Error("Usage: makefx assets clone <variant-id> --from-space <source-space-id> --to-space <target-space-id>");
|
|
8834
8970
|
const sourceSpaceId = requireOption(parsed, ["from-space", "source-space"], "Usage: makefx assets clone <variant-id> --from-space <source-space-id> --to-space <target-space-id>");
|
|
8835
8971
|
const targetSpaceId = requireOption(parsed, ["to-space", "target-space"], "Usage: makefx assets clone <variant-id> --from-space <source-space-id> --to-space <target-space-id>");
|
|
@@ -8837,8 +8973,8 @@ async function cloneAsset(parsed, deps) {
|
|
|
8837
8973
|
sourceSpaceId,
|
|
8838
8974
|
sourceVariantId
|
|
8839
8975
|
};
|
|
8840
|
-
const name = normalizeOption(parsed.options.name);
|
|
8841
|
-
const type = normalizeOption(parsed.options.type);
|
|
8976
|
+
const name = normalizeOption$1(parsed.options.name);
|
|
8977
|
+
const type = normalizeOption$1(parsed.options.type);
|
|
8842
8978
|
if (name) body.name = name;
|
|
8843
8979
|
if (type) body.type = type;
|
|
8844
8980
|
const response = await deps.fetch(`${ctx.baseUrl}/api/spaces/${encodeURIComponent(targetSpaceId)}/assets/clone`, {
|
|
@@ -8886,10 +9022,10 @@ async function recordDownloadedMirror(input) {
|
|
|
8886
9022
|
}
|
|
8887
9023
|
}
|
|
8888
9024
|
async function listAssets(ctx, deps) {
|
|
8889
|
-
return (await fetchJson(ctx, deps, `/api/spaces/${ctx.spaceId}/assets`)).assets || [];
|
|
9025
|
+
return (await fetchJson$1(ctx, deps, `/api/spaces/${ctx.spaceId}/assets`)).assets || [];
|
|
8890
9026
|
}
|
|
8891
9027
|
async function getAssetDetails(ctx, deps, assetId) {
|
|
8892
|
-
return fetchJson(ctx, deps, `/api/spaces/${ctx.spaceId}/assets/${assetId}`);
|
|
9028
|
+
return fetchJson$1(ctx, deps, `/api/spaces/${ctx.spaceId}/assets/${assetId}`);
|
|
8893
9029
|
}
|
|
8894
9030
|
async function setActiveVariant(ctx, deps, assetId, variantId) {
|
|
8895
9031
|
try {
|
|
@@ -8901,7 +9037,63 @@ async function setActiveVariant(ctx, deps, assetId, variantId) {
|
|
|
8901
9037
|
throw error;
|
|
8902
9038
|
}
|
|
8903
9039
|
}
|
|
8904
|
-
async function
|
|
9040
|
+
async function getFailedDownloadVariantMessage(error, resolved, ctx, deps) {
|
|
9041
|
+
if (resolved.variant || !resolved.requestPath.includes("/variants/")) return null;
|
|
9042
|
+
if (!isVariantMediaUnavailableError(error)) return null;
|
|
9043
|
+
const variantId = resolved.mediaKey;
|
|
9044
|
+
let state;
|
|
9045
|
+
try {
|
|
9046
|
+
state = await requestSpaceState(ctx, deps);
|
|
9047
|
+
} catch {
|
|
9048
|
+
return null;
|
|
9049
|
+
}
|
|
9050
|
+
const variant = state.variants.find((candidate) => {
|
|
9051
|
+
return isVariantRecord(candidate) && candidate.id === variantId;
|
|
9052
|
+
});
|
|
9053
|
+
if (!variant || variant.status !== "failed") return null;
|
|
9054
|
+
const reason = formatGenerationFailureMessage(variant.error_message, variant.provider_metadata);
|
|
9055
|
+
return `Variant ${variant.id} failed and has no downloadable media${reason ? `: ${reason}` : "."}`;
|
|
9056
|
+
}
|
|
9057
|
+
function isVariantMediaUnavailableError(error) {
|
|
9058
|
+
return error instanceof Error && error.message.includes("Variant media not available");
|
|
9059
|
+
}
|
|
9060
|
+
function isVariantRecord(value) {
|
|
9061
|
+
return Boolean(value && typeof value === "object" && typeof value.id === "string");
|
|
9062
|
+
}
|
|
9063
|
+
async function requestSpaceState(ctx, deps) {
|
|
9064
|
+
const client = await deps.createMutationClient(ctx.env, ctx.spaceId);
|
|
9065
|
+
await client.connect();
|
|
9066
|
+
try {
|
|
9067
|
+
return await new Promise((resolve, reject) => {
|
|
9068
|
+
const syncClient = client;
|
|
9069
|
+
if (typeof syncClient.setOnSyncState !== "function" || typeof syncClient.requestSync !== "function") {
|
|
9070
|
+
reject(/* @__PURE__ */ new Error("Space sync is not available"));
|
|
9071
|
+
return;
|
|
9072
|
+
}
|
|
9073
|
+
let settled = false;
|
|
9074
|
+
const finish = (callback) => {
|
|
9075
|
+
if (settled) return;
|
|
9076
|
+
settled = true;
|
|
9077
|
+
clearTimeout(timer);
|
|
9078
|
+
callback();
|
|
9079
|
+
};
|
|
9080
|
+
const timer = setTimeout(() => {
|
|
9081
|
+
finish(() => reject(/* @__PURE__ */ new Error("Timed out waiting for space sync state")));
|
|
9082
|
+
}, 3e4);
|
|
9083
|
+
syncClient.setOnSyncState((state) => {
|
|
9084
|
+
finish(() => resolve(state));
|
|
9085
|
+
});
|
|
9086
|
+
try {
|
|
9087
|
+
syncClient.requestSync();
|
|
9088
|
+
} catch (error) {
|
|
9089
|
+
finish(() => reject(error));
|
|
9090
|
+
}
|
|
9091
|
+
});
|
|
9092
|
+
} finally {
|
|
9093
|
+
client.disconnect();
|
|
9094
|
+
}
|
|
9095
|
+
}
|
|
9096
|
+
async function fetchJson$1(ctx, deps, apiPath) {
|
|
8905
9097
|
const response = await deps.fetch(`${ctx.baseUrl}${apiPath}`, { headers: {
|
|
8906
9098
|
"Authorization": `Bearer ${ctx.accessToken}`,
|
|
8907
9099
|
"Accept": "application/json"
|
|
@@ -9083,7 +9275,7 @@ function formatTimestamp(value) {
|
|
|
9083
9275
|
if (Number.isNaN(date.getTime())) return String(value);
|
|
9084
9276
|
return date.toISOString().replace("T", " ").replace(/\.\d{3}Z$/, "Z").slice(0, 20);
|
|
9085
9277
|
}
|
|
9086
|
-
function printUsage$
|
|
9278
|
+
function printUsage$3() {
|
|
9087
9279
|
console.log(`
|
|
9088
9280
|
Usage:
|
|
9089
9281
|
makefx assets
|
|
@@ -9100,7 +9292,7 @@ Usage:
|
|
|
9100
9292
|
}
|
|
9101
9293
|
//#endregion
|
|
9102
9294
|
//#region src/cli/commands/variants.ts
|
|
9103
|
-
var defaultDeps$
|
|
9295
|
+
var defaultDeps$3 = {
|
|
9104
9296
|
loadConfig: loadStoredConfig,
|
|
9105
9297
|
loadProjectConfig,
|
|
9106
9298
|
resolveBaseUrl,
|
|
@@ -9112,12 +9304,12 @@ async function handleVariants(parsed) {
|
|
|
9112
9304
|
await executeVariants(parsed);
|
|
9113
9305
|
} catch (error) {
|
|
9114
9306
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
9115
|
-
printUsage$
|
|
9307
|
+
printUsage$2();
|
|
9116
9308
|
process$1.exitCode = 1;
|
|
9117
9309
|
}
|
|
9118
9310
|
}
|
|
9119
|
-
async function executeVariants(parsed, deps = defaultDeps$
|
|
9120
|
-
const ctx = await buildContext$
|
|
9311
|
+
async function executeVariants(parsed, deps = defaultDeps$3) {
|
|
9312
|
+
const ctx = await buildContext$3(parsed, deps);
|
|
9121
9313
|
const subcommand = parsed.positionals[0];
|
|
9122
9314
|
if (subcommand === "delete") {
|
|
9123
9315
|
const variantId = requireVariantId(parsed, "delete");
|
|
@@ -9165,7 +9357,7 @@ function requireVariantId(parsed, verb) {
|
|
|
9165
9357
|
if (!variantId) throw new Error(`Variant ID is required: makefx variants ${verb} <variant-id>`);
|
|
9166
9358
|
return variantId;
|
|
9167
9359
|
}
|
|
9168
|
-
async function buildContext$
|
|
9360
|
+
async function buildContext$3(parsed, deps) {
|
|
9169
9361
|
const projectConfig = await deps.loadProjectConfig();
|
|
9170
9362
|
const env = resolveCommandEnvironment(parsed, projectConfig);
|
|
9171
9363
|
const spaceId = resolveCommandSpace(parsed, projectConfig);
|
|
@@ -9188,7 +9380,7 @@ async function withVariantClient(ctx, deps, run) {
|
|
|
9188
9380
|
client.disconnect();
|
|
9189
9381
|
}
|
|
9190
9382
|
}
|
|
9191
|
-
function printUsage$
|
|
9383
|
+
function printUsage$2() {
|
|
9192
9384
|
console.log(`
|
|
9193
9385
|
Usage:
|
|
9194
9386
|
makefx variants delete <variant-id>
|
|
@@ -9204,6 +9396,251 @@ Options:
|
|
|
9204
9396
|
`);
|
|
9205
9397
|
}
|
|
9206
9398
|
//#endregion
|
|
9399
|
+
//#region src/cli/commands/collections.ts
|
|
9400
|
+
var COLLECTION_KINDS = new Set([
|
|
9401
|
+
"cast",
|
|
9402
|
+
"backgrounds",
|
|
9403
|
+
"scenes",
|
|
9404
|
+
"thumbnails",
|
|
9405
|
+
"maps",
|
|
9406
|
+
"deliverables",
|
|
9407
|
+
"custom"
|
|
9408
|
+
]);
|
|
9409
|
+
var defaultDeps$2 = {
|
|
9410
|
+
loadConfig: loadStoredConfig,
|
|
9411
|
+
loadProjectConfig,
|
|
9412
|
+
resolveBaseUrl,
|
|
9413
|
+
fetch,
|
|
9414
|
+
createMutationClient: (env, spaceId) => WebSocketClient.create(env, spaceId),
|
|
9415
|
+
print: console.log
|
|
9416
|
+
};
|
|
9417
|
+
async function handleCollections(parsed) {
|
|
9418
|
+
try {
|
|
9419
|
+
await executeCollections(parsed);
|
|
9420
|
+
} catch (error) {
|
|
9421
|
+
console.error("Error:", error instanceof Error ? error.message : error);
|
|
9422
|
+
printUsage$1();
|
|
9423
|
+
process$1.exitCode = 1;
|
|
9424
|
+
}
|
|
9425
|
+
}
|
|
9426
|
+
async function executeCollections(parsed, deps = defaultDeps$2) {
|
|
9427
|
+
const subcommand = parsed.positionals[0] || "list";
|
|
9428
|
+
const ctx = await buildContext$2(parsed, deps);
|
|
9429
|
+
if (subcommand === "list") {
|
|
9430
|
+
const collections = await listCollections(ctx, deps);
|
|
9431
|
+
if (parsed.options.json === "true") deps.print(JSON.stringify(collections, null, 2));
|
|
9432
|
+
else printCollections(collections, deps.print);
|
|
9433
|
+
return {
|
|
9434
|
+
type: "list",
|
|
9435
|
+
collections
|
|
9436
|
+
};
|
|
9437
|
+
}
|
|
9438
|
+
if (subcommand === "items") {
|
|
9439
|
+
const collectionId = parsed.positionals[1];
|
|
9440
|
+
if (!collectionId) throw new Error("Collection ID is required: makefx collections items <collection-id>");
|
|
9441
|
+
const items = await listCollectionItems(ctx, deps, collectionId);
|
|
9442
|
+
if (parsed.options.json === "true") deps.print(JSON.stringify(items, null, 2));
|
|
9443
|
+
else printCollectionItems(items, deps.print);
|
|
9444
|
+
return {
|
|
9445
|
+
type: "items",
|
|
9446
|
+
items
|
|
9447
|
+
};
|
|
9448
|
+
}
|
|
9449
|
+
if (subcommand === "create") {
|
|
9450
|
+
const name = parsed.positionals.slice(1).join(" ").trim() || normalizeOption(parsed.options.name);
|
|
9451
|
+
if (!name) throw new Error("Usage: makefx collections create \"<name>\"");
|
|
9452
|
+
const collection = await withCollectionClient(ctx, deps, (client) => client.createCollection({
|
|
9453
|
+
id: normalizeOption(parsed.options.id),
|
|
9454
|
+
name,
|
|
9455
|
+
kind: parseKind(normalizeOption(parsed.options.kind)),
|
|
9456
|
+
color: parseNullableOption(parsed.options.color),
|
|
9457
|
+
description: parseNullableOption(parsed.options.description),
|
|
9458
|
+
sortIndex: parseOptionalInteger(parsed.options["sort-index"], "sort-index")
|
|
9459
|
+
}));
|
|
9460
|
+
printJsonOrLine(parsed, deps, collection, `Created collection ${collection.id} (${collection.name})`);
|
|
9461
|
+
return {
|
|
9462
|
+
type: "create",
|
|
9463
|
+
collection
|
|
9464
|
+
};
|
|
9465
|
+
}
|
|
9466
|
+
if (subcommand === "delete") {
|
|
9467
|
+
const collectionId = parsed.positionals[1];
|
|
9468
|
+
if (!collectionId) throw new Error("Collection ID is required: makefx collections delete <collection-id>");
|
|
9469
|
+
await withCollectionClient(ctx, deps, (client) => client.deleteCollection(collectionId));
|
|
9470
|
+
deps.print(`Deleted collection ${collectionId}`);
|
|
9471
|
+
return {
|
|
9472
|
+
type: "delete",
|
|
9473
|
+
collectionId
|
|
9474
|
+
};
|
|
9475
|
+
}
|
|
9476
|
+
if (subcommand === "add-asset") {
|
|
9477
|
+
const collectionId = parsed.positionals[1];
|
|
9478
|
+
const assetId = parsed.positionals[2] || normalizeOption(parsed.options.asset);
|
|
9479
|
+
if (!collectionId || !assetId) throw new Error("Usage: makefx collections add-asset <collection-id> <asset-id>");
|
|
9480
|
+
const item = await withCollectionClient(ctx, deps, (client) => client.createCollectionItem({
|
|
9481
|
+
collectionId,
|
|
9482
|
+
id: normalizeOption(parsed.options.id),
|
|
9483
|
+
subjectType: "asset",
|
|
9484
|
+
assetId,
|
|
9485
|
+
role: normalizeOption(parsed.options.role),
|
|
9486
|
+
pinnedVariantId: parseNullableOption(parsed.options.variant ?? parsed.options["pinned-variant"]),
|
|
9487
|
+
sortIndex: parseOptionalInteger(parsed.options["sort-index"], "sort-index")
|
|
9488
|
+
}));
|
|
9489
|
+
printJsonOrLine(parsed, deps, item, `Added asset ${assetId} to collection ${collectionId} as item ${item.id}`);
|
|
9490
|
+
return {
|
|
9491
|
+
type: "add",
|
|
9492
|
+
item
|
|
9493
|
+
};
|
|
9494
|
+
}
|
|
9495
|
+
if (subcommand === "add-variant") {
|
|
9496
|
+
const collectionId = parsed.positionals[1];
|
|
9497
|
+
const variantId = parsed.positionals[2] || normalizeOption(parsed.options.variant);
|
|
9498
|
+
if (!collectionId || !variantId) throw new Error("Usage: makefx collections add-variant <collection-id> <variant-id>");
|
|
9499
|
+
const item = await withCollectionClient(ctx, deps, (client) => client.createCollectionItem({
|
|
9500
|
+
collectionId,
|
|
9501
|
+
id: normalizeOption(parsed.options.id),
|
|
9502
|
+
subjectType: "variant",
|
|
9503
|
+
variantId,
|
|
9504
|
+
role: normalizeOption(parsed.options.role),
|
|
9505
|
+
sortIndex: parseOptionalInteger(parsed.options["sort-index"], "sort-index")
|
|
9506
|
+
}));
|
|
9507
|
+
printJsonOrLine(parsed, deps, item, `Added variant ${variantId} to collection ${collectionId} as item ${item.id}`);
|
|
9508
|
+
return {
|
|
9509
|
+
type: "add",
|
|
9510
|
+
item
|
|
9511
|
+
};
|
|
9512
|
+
}
|
|
9513
|
+
if (subcommand === "remove") {
|
|
9514
|
+
const collectionId = parsed.positionals[1];
|
|
9515
|
+
const itemId = parsed.positionals[2] || normalizeOption(parsed.options.item);
|
|
9516
|
+
if (!collectionId || !itemId) throw new Error("Usage: makefx collections remove <collection-id> <item-id>");
|
|
9517
|
+
await withCollectionClient(ctx, deps, (client) => client.deleteCollectionItem(collectionId, itemId));
|
|
9518
|
+
deps.print(`Removed item ${itemId} from collection ${collectionId}`);
|
|
9519
|
+
return {
|
|
9520
|
+
type: "remove",
|
|
9521
|
+
collectionId,
|
|
9522
|
+
itemId
|
|
9523
|
+
};
|
|
9524
|
+
}
|
|
9525
|
+
if (subcommand === "reorder") {
|
|
9526
|
+
const collectionId = parsed.positionals[1];
|
|
9527
|
+
const itemIds = splitIds(parsed.positionals[2] || normalizeOption(parsed.options.items));
|
|
9528
|
+
if (!collectionId || itemIds.length === 0) throw new Error("Usage: makefx collections reorder <collection-id> <item-id,item-id,...>");
|
|
9529
|
+
const items = await withCollectionClient(ctx, deps, (client) => client.reorderCollectionItems(collectionId, itemIds));
|
|
9530
|
+
if (parsed.options.json === "true") deps.print(JSON.stringify(items, null, 2));
|
|
9531
|
+
else deps.print(`Reordered ${items.length} item(s) in collection ${collectionId}`);
|
|
9532
|
+
return {
|
|
9533
|
+
type: "reorder",
|
|
9534
|
+
items
|
|
9535
|
+
};
|
|
9536
|
+
}
|
|
9537
|
+
throw new Error(`Unknown collections command: ${subcommand}`);
|
|
9538
|
+
}
|
|
9539
|
+
async function buildContext$2(parsed, deps) {
|
|
9540
|
+
const projectConfig = await deps.loadProjectConfig();
|
|
9541
|
+
const env = resolveCommandEnvironment(parsed, projectConfig);
|
|
9542
|
+
const spaceId = resolveCommandSpace(parsed, projectConfig);
|
|
9543
|
+
if (!spaceId) throw new Error("--space is required, or run: makefx init --space <id>");
|
|
9544
|
+
const config = await deps.loadConfig(env);
|
|
9545
|
+
if (!config) throw new Error(`Not logged in to ${env} environment. Run: ${loginCommandForEnvironment(env)}`);
|
|
9546
|
+
if (config.token.expiresAt < Date.now()) throw new Error(`Token expired for ${env} environment. Run: ${loginCommandForEnvironment(env)}`);
|
|
9547
|
+
if (env === "local") process$1.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
9548
|
+
return {
|
|
9549
|
+
env,
|
|
9550
|
+
spaceId,
|
|
9551
|
+
baseUrl: deps.resolveBaseUrl(env),
|
|
9552
|
+
accessToken: config.token.accessToken
|
|
9553
|
+
};
|
|
9554
|
+
}
|
|
9555
|
+
async function withCollectionClient(ctx, deps, run) {
|
|
9556
|
+
const client = await deps.createMutationClient(ctx.env, ctx.spaceId);
|
|
9557
|
+
await client.connect();
|
|
9558
|
+
try {
|
|
9559
|
+
return await run(client);
|
|
9560
|
+
} finally {
|
|
9561
|
+
client.disconnect();
|
|
9562
|
+
}
|
|
9563
|
+
}
|
|
9564
|
+
async function listCollections(ctx, deps) {
|
|
9565
|
+
return (await fetchJson(ctx, deps, `/api/spaces/${encodeURIComponent(ctx.spaceId)}/collections`)).collections || [];
|
|
9566
|
+
}
|
|
9567
|
+
async function listCollectionItems(ctx, deps, collectionId) {
|
|
9568
|
+
return (await fetchJson(ctx, deps, `/api/spaces/${encodeURIComponent(ctx.spaceId)}/collections/${encodeURIComponent(collectionId)}/items`)).items || [];
|
|
9569
|
+
}
|
|
9570
|
+
async function fetchJson(ctx, deps, apiPath) {
|
|
9571
|
+
const response = await deps.fetch(`${ctx.baseUrl}${apiPath}`, { headers: {
|
|
9572
|
+
"Authorization": `Bearer ${ctx.accessToken}`,
|
|
9573
|
+
"Accept": "application/json"
|
|
9574
|
+
} });
|
|
9575
|
+
if (!response.ok) {
|
|
9576
|
+
const errorText = await response.text();
|
|
9577
|
+
throw new Error(`Request failed (${response.status}): ${errorText || response.statusText}`);
|
|
9578
|
+
}
|
|
9579
|
+
return response.json();
|
|
9580
|
+
}
|
|
9581
|
+
function normalizeOption(value) {
|
|
9582
|
+
return !value || value === "true" ? void 0 : value;
|
|
9583
|
+
}
|
|
9584
|
+
function parseNullableOption(value) {
|
|
9585
|
+
if (value === void 0) return void 0;
|
|
9586
|
+
if (value === "true") return void 0;
|
|
9587
|
+
if (value === "" || value === "null" || value === "none") return null;
|
|
9588
|
+
return value;
|
|
9589
|
+
}
|
|
9590
|
+
function parseKind(value) {
|
|
9591
|
+
if (!value) return void 0;
|
|
9592
|
+
if (!COLLECTION_KINDS.has(value)) throw new Error(`Invalid collection kind "${value}". Expected one of: ${Array.from(COLLECTION_KINDS).join(", ")}`);
|
|
9593
|
+
return value;
|
|
9594
|
+
}
|
|
9595
|
+
function parseOptionalInteger(value, name) {
|
|
9596
|
+
const normalized = normalizeOption(value);
|
|
9597
|
+
if (!normalized) return void 0;
|
|
9598
|
+
const parsed = Number.parseInt(normalized, 10);
|
|
9599
|
+
if (!Number.isInteger(parsed) || String(parsed) !== normalized) throw new Error(`--${name} must be an integer`);
|
|
9600
|
+
return parsed;
|
|
9601
|
+
}
|
|
9602
|
+
function splitIds(value) {
|
|
9603
|
+
return (value ?? "").split(",").map((item) => item.trim()).filter(Boolean);
|
|
9604
|
+
}
|
|
9605
|
+
function printJsonOrLine(parsed, deps, value, line) {
|
|
9606
|
+
if (parsed.options.json === "true") deps.print(JSON.stringify(value, null, 2));
|
|
9607
|
+
else deps.print(line);
|
|
9608
|
+
}
|
|
9609
|
+
function printCollections(collections, print) {
|
|
9610
|
+
if (collections.length === 0) {
|
|
9611
|
+
print("No collections found.");
|
|
9612
|
+
return;
|
|
9613
|
+
}
|
|
9614
|
+
print(`Found ${collections.length} collection(s):\n`);
|
|
9615
|
+
print("Sort".padEnd(8) + "Kind".padEnd(15) + "Collection".padEnd(38) + "Name");
|
|
9616
|
+
print("-".repeat(85));
|
|
9617
|
+
for (const collection of collections) print(String(collection.sort_index).padEnd(8) + truncate(collection.kind, 13).padEnd(15) + truncate(collection.id, 36).padEnd(38) + truncate(collection.name, 40));
|
|
9618
|
+
}
|
|
9619
|
+
function printCollectionItems(items, print) {
|
|
9620
|
+
if (items.length === 0) {
|
|
9621
|
+
print("No collection items found.");
|
|
9622
|
+
return;
|
|
9623
|
+
}
|
|
9624
|
+
print(`Found ${items.length} collection item(s):\n`);
|
|
9625
|
+
print("Sort".padEnd(8) + "Subject".padEnd(10) + "Item".padEnd(34) + "Asset".padEnd(28) + "Variant".padEnd(28) + "Role");
|
|
9626
|
+
print("-".repeat(128));
|
|
9627
|
+
for (const item of items) print(String(item.sort_index).padEnd(8) + item.subject_type.padEnd(10) + truncate(item.id, 32).padEnd(34) + truncate(item.asset_id || "-", 26).padEnd(28) + truncate(item.variant_id || item.pinned_variant_id || "-", 26).padEnd(28) + truncate(item.role, 24));
|
|
9628
|
+
}
|
|
9629
|
+
function printUsage$1() {
|
|
9630
|
+
console.log(`
|
|
9631
|
+
Usage:
|
|
9632
|
+
makefx collections
|
|
9633
|
+
makefx collections --json
|
|
9634
|
+
makefx collections create "<name>" [--kind custom]
|
|
9635
|
+
makefx collections delete <collection-id>
|
|
9636
|
+
makefx collections items <collection-id>
|
|
9637
|
+
makefx collections add-asset <collection-id> <asset-id> [--variant <variant-id>] [--role <role>]
|
|
9638
|
+
makefx collections add-variant <collection-id> <variant-id> [--role <role>]
|
|
9639
|
+
makefx collections remove <collection-id> <item-id>
|
|
9640
|
+
makefx collections reorder <collection-id> <item-id,item-id,...>
|
|
9641
|
+
`);
|
|
9642
|
+
}
|
|
9643
|
+
//#endregion
|
|
9207
9644
|
//#region src/cli/commands/usage.ts
|
|
9208
9645
|
var defaultDeps$1 = {
|
|
9209
9646
|
loadConfig: loadStoredConfig,
|
|
@@ -9504,7 +9941,7 @@ Options:
|
|
|
9504
9941
|
}
|
|
9505
9942
|
//#endregion
|
|
9506
9943
|
//#region src/cli/index.ts
|
|
9507
|
-
var CLI_VERSION = "1.0.
|
|
9944
|
+
var CLI_VERSION = "1.0.7+686298a71cee";
|
|
9508
9945
|
async function main() {
|
|
9509
9946
|
const argv = process$1.argv.slice(2);
|
|
9510
9947
|
if (argv[0] === "--") argv.shift();
|
|
@@ -9555,7 +9992,8 @@ function imageCapabilityHelp() {
|
|
|
9555
9992
|
--size <value> Output size (${sizeLines})
|
|
9556
9993
|
--aspect <ratio> Aspect ratio: ${imageAspectValues()}
|
|
9557
9994
|
--refs <refs> Reference limit (${referenceLines})
|
|
9558
|
-
--follow <id> Resume/download a variant after a long generation or disconnect
|
|
9995
|
+
--follow <id> Resume/download a variant after a long generation or disconnect
|
|
9996
|
+
--collection <id> Place the completed asset in a Space collection`;
|
|
9559
9997
|
}
|
|
9560
9998
|
function videoResolutionValues() {
|
|
9561
9999
|
return optionValues(uniqueValues(VIDEO_GENERATION_TIERS.flatMap((tier) => getVideoGenerationResolutionsForTier(tier))));
|
|
@@ -9583,6 +10021,7 @@ function videoCapabilityHelp() {
|
|
|
9583
10021
|
--first-frame <ref> Veo start frame image variant or local image path
|
|
9584
10022
|
--last-frame <ref> Veo final frame image variant or local image path
|
|
9585
10023
|
--follow <id> Resume/download a variant after a long generation or disconnect
|
|
10024
|
+
--collection <id> Place the completed asset in a Space collection
|
|
9586
10025
|
|
|
9587
10026
|
Veo 3.1 frames:
|
|
9588
10027
|
--first-frame resolves to the first referenceVariantId and becomes the Veo top-level image input.
|
|
@@ -9649,6 +10088,10 @@ function printCommandHelp(command, positionals) {
|
|
|
9649
10088
|
case "assets":
|
|
9650
10089
|
printAssetsHelp();
|
|
9651
10090
|
return;
|
|
10091
|
+
case "collections":
|
|
10092
|
+
case "collection":
|
|
10093
|
+
printCollectionsHelp();
|
|
10094
|
+
return;
|
|
9652
10095
|
case "usage":
|
|
9653
10096
|
printUsageHelp();
|
|
9654
10097
|
return;
|
|
@@ -9695,6 +10138,8 @@ Inspect:
|
|
|
9695
10138
|
assets show <asset-id> Show variants and lineage
|
|
9696
10139
|
assets download <variant-id> -o <file> Download variant media
|
|
9697
10140
|
assets clone <variant-id> --from-space <id> --to-space <id>
|
|
10141
|
+
collections add-asset <collection-id> <asset-id>
|
|
10142
|
+
collections add-variant <collection-id> <variant-id>
|
|
9698
10143
|
variants rate <variant-id> approved|rejected
|
|
9699
10144
|
variants star <variant-id>
|
|
9700
10145
|
|
|
@@ -9703,6 +10148,7 @@ Details:
|
|
|
9703
10148
|
help audio Speech, dialogue, music, and SFX
|
|
9704
10149
|
help video Video generate/refine/derive and keyframes
|
|
9705
10150
|
help assets Asset inspection and downloads
|
|
10151
|
+
help collections Space collection organization
|
|
9706
10152
|
help spaces Space setup and selection
|
|
9707
10153
|
help upload Upload local media into a Space
|
|
9708
10154
|
|
|
@@ -9740,7 +10186,8 @@ Examples:
|
|
|
9740
10186
|
makefx derive --refs character.png,background.png --name "Hero Scene" --type scene "Place the character in the background" -o hero-scene.png
|
|
9741
10187
|
makefx refine --variant variant_123 "Keep composition, make the lighting warmer" -o warm.png
|
|
9742
10188
|
|
|
9743
|
-
If the CLI stops waiting after a job has started,
|
|
10189
|
+
If the CLI stops waiting after a job has started, the job keeps running in Make Effects.
|
|
10190
|
+
Rerun the printed --follow command to resume the same variant instead of starting a duplicate.
|
|
9744
10191
|
`);
|
|
9745
10192
|
}
|
|
9746
10193
|
function printInitHelp() {
|
|
@@ -9834,31 +10281,33 @@ function printForgeHelp(command) {
|
|
|
9834
10281
|
if (command === "generate") {
|
|
9835
10282
|
console.log(`
|
|
9836
10283
|
Usage:
|
|
9837
|
-
makefx generate "prompt" --name <name> --type <type> -o <file> [--model ${optionValues(IMAGE_MODEL_SELECTIONS)}] [--size ${imageSizeValues()}] [--aspect <ratio>] [--space <id>]
|
|
9838
|
-
makefx generate --follow <variant_id> -o <file> [--space <id>]
|
|
10284
|
+
makefx generate "prompt" --name <name> --type <type> -o <file> [--model ${optionValues(IMAGE_MODEL_SELECTIONS)}] [--size ${imageSizeValues()}] [--aspect <ratio>] [--collection <id>] [--space <id>]
|
|
10285
|
+
makefx generate --follow <variant_id> -o <file> [--collection <id>] [--space <id>]
|
|
9839
10286
|
|
|
9840
10287
|
${imageCapabilityHelp()}
|
|
9841
10288
|
|
|
9842
|
-
If the CLI stops waiting after a job has started,
|
|
10289
|
+
If the CLI stops waiting after a job has started, the job keeps running in Make Effects.
|
|
10290
|
+
Rerun the printed --follow command to resume the same variant instead of starting a duplicate.
|
|
9843
10291
|
`);
|
|
9844
10292
|
return;
|
|
9845
10293
|
}
|
|
9846
10294
|
if (command === "refine") {
|
|
9847
10295
|
console.log(`
|
|
9848
10296
|
Usage:
|
|
9849
|
-
makefx refine --variant <variant_id> "prompt" -o <file> [--model ${optionValues(IMAGE_MODEL_SELECTIONS)}] [--size ${imageSizeValues()}] [--aspect <ratio>] [--space <id>]
|
|
9850
|
-
makefx refine --follow <variant_id> -o <file> [--space <id>]
|
|
10297
|
+
makefx refine --variant <variant_id> "prompt" -o <file> [--model ${optionValues(IMAGE_MODEL_SELECTIONS)}] [--size ${imageSizeValues()}] [--aspect <ratio>] [--collection <id>] [--space <id>]
|
|
10298
|
+
makefx refine --follow <variant_id> -o <file> [--collection <id>] [--space <id>]
|
|
9851
10299
|
|
|
9852
10300
|
${imageCapabilityHelp()}
|
|
9853
10301
|
|
|
9854
|
-
If the CLI stops waiting after a job has started,
|
|
10302
|
+
If the CLI stops waiting after a job has started, the job keeps running in Make Effects.
|
|
10303
|
+
Rerun the printed --follow command to resume the same variant instead of starting a duplicate.
|
|
9855
10304
|
`);
|
|
9856
10305
|
return;
|
|
9857
10306
|
}
|
|
9858
10307
|
if (command === "batch") {
|
|
9859
10308
|
console.log(`
|
|
9860
10309
|
Usage:
|
|
9861
|
-
makefx batch "prompt" --name <name> --type <type> --count <2-8> --output-dir <dir> [--model ${optionValues(IMAGE_MODEL_SELECTIONS)}] [--size ${imageSizeValues()}] [--aspect <ratio>]
|
|
10310
|
+
makefx batch "prompt" --name <name> --type <type> --count <2-8> --output-dir <dir> [--model ${optionValues(IMAGE_MODEL_SELECTIONS)}] [--size ${imageSizeValues()}] [--aspect <ratio>] [--collection <id>]
|
|
9862
10311
|
|
|
9863
10312
|
${imageCapabilityHelp()}
|
|
9864
10313
|
|
|
@@ -9869,12 +10318,13 @@ Batch creates several variants. If waiting stops, inspect the Space or download
|
|
|
9869
10318
|
}
|
|
9870
10319
|
console.log(`
|
|
9871
10320
|
Usage:
|
|
9872
|
-
makefx derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--model ${optionValues(IMAGE_MODEL_SELECTIONS)}] [--size ${imageSizeValues()}] [--aspect <ratio>] [--space <id>]
|
|
9873
|
-
makefx derive --follow <variant_id> -o <file> [--space <id>]
|
|
10321
|
+
makefx derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--model ${optionValues(IMAGE_MODEL_SELECTIONS)}] [--size ${imageSizeValues()}] [--aspect <ratio>] [--collection <id>] [--space <id>]
|
|
10322
|
+
makefx derive --follow <variant_id> -o <file> [--collection <id>] [--space <id>]
|
|
9874
10323
|
|
|
9875
10324
|
${imageCapabilityHelp()}
|
|
9876
10325
|
|
|
9877
|
-
If the CLI stops waiting after a job has started,
|
|
10326
|
+
If the CLI stops waiting after a job has started, the job keeps running in Make Effects.
|
|
10327
|
+
Rerun the printed --follow command to resume the same variant instead of starting a duplicate.
|
|
9878
10328
|
`);
|
|
9879
10329
|
}
|
|
9880
10330
|
function printAudioHelp(positionals) {
|
|
@@ -9893,23 +10343,24 @@ Lists ElevenLabs voices available to the connected account when ElevenLabs is th
|
|
|
9893
10343
|
if (second === "generate") {
|
|
9894
10344
|
console.log(`
|
|
9895
10345
|
Usage:
|
|
9896
|
-
makefx audio ${first} generate "prompt" --name <name> -o <file> [--space <id>]
|
|
9897
|
-
makefx audio ${first} generate --input <file> --name <name> -o <file> [--space <id>]
|
|
9898
|
-
makefx audio ${first} generate --follow <variant_id> -o <file> [--space <id>]
|
|
9899
|
-
${first === "music" ? " makefx audio music generate \"prompt\" --provider lyria --name <name> -o <file> [--space <id>]\n" : ""}
|
|
10346
|
+
makefx audio ${first} generate "prompt" --name <name> -o <file> [--collection <id>] [--space <id>]
|
|
10347
|
+
makefx audio ${first} generate --input <file> --name <name> -o <file> [--collection <id>] [--space <id>]
|
|
10348
|
+
makefx audio ${first} generate --follow <variant_id> -o <file> [--collection <id>] [--space <id>]
|
|
10349
|
+
${first === "music" ? " makefx audio music generate \"prompt\" --provider lyria --name <name> -o <file> [--collection <id>] [--space <id>]\n" : ""}
|
|
9900
10350
|
${first === "music" ? "Provider selection:\n --provider <elevenlabs|lyria> Music provider (default: server default)\n" : ""}
|
|
9901
10351
|
${first === "speech" || first === "dialogue" ? "Model selection:\n --model <model_id> ElevenLabs model (default: eleven_v3)\n" : ""}
|
|
9902
10352
|
${first === "speech" || first === "dialogue" ? "Voice selection:\n --voice <voice_id> Speech voice, or dialogue fallback voice\n --dialogue-voices <id,id,...> Dialogue voices ordered by first speaker appearance\n" : ""}
|
|
9903
10353
|
Long runs:
|
|
9904
10354
|
--follow <variant_id> Resume/download a variant after a long generation or disconnect
|
|
10355
|
+
--collection <id> Place the completed asset in a Space collection
|
|
9905
10356
|
`);
|
|
9906
10357
|
return;
|
|
9907
10358
|
}
|
|
9908
10359
|
if (second === "batch") {
|
|
9909
10360
|
console.log(`
|
|
9910
10361
|
Usage:
|
|
9911
|
-
makefx audio ${first} batch "prompt" --name <name> --count <2-8> --output-dir <dir> [--space <id>]
|
|
9912
|
-
${first === "music" ? " makefx audio music batch \"prompt\" --provider lyria --name <name> --count <2-8> --output-dir <dir> [--space <id>]\n" : ""}
|
|
10362
|
+
makefx audio ${first} batch "prompt" --name <name> --count <2-8> --output-dir <dir> [--collection <id>] [--space <id>]
|
|
10363
|
+
${first === "music" ? " makefx audio music batch \"prompt\" --provider lyria --name <name> --count <2-8> --output-dir <dir> [--collection <id>] [--space <id>]\n" : ""}
|
|
9913
10364
|
${first === "music" ? "Provider selection:\n --provider <elevenlabs|lyria> Music provider (default: server default)\n" : ""}
|
|
9914
10365
|
${first === "speech" || first === "dialogue" ? "Model selection:\n --model <model_id> ElevenLabs model (default: eleven_v3)\n" : ""}
|
|
9915
10366
|
${first === "speech" || first === "dialogue" ? "Voice selection:\n --voice <voice_id> Speech voice, or dialogue fallback voice\n --dialogue-voices <id,id,...> Dialogue voices ordered by first speaker appearance\n" : ""}
|
|
@@ -9918,8 +10369,8 @@ ${first === "speech" || first === "dialogue" ? "Voice selection:\n --voice <voi
|
|
|
9918
10369
|
}
|
|
9919
10370
|
console.log(`
|
|
9920
10371
|
Usage:
|
|
9921
|
-
makefx audio ${first} generate "prompt" --name <name> -o <file> [--space <id>]
|
|
9922
|
-
makefx audio ${first} batch "prompt" --name <name> --count <2-8> --output-dir <dir> [--space <id>]
|
|
10372
|
+
makefx audio ${first} generate "prompt" --name <name> -o <file> [--collection <id>] [--space <id>]
|
|
10373
|
+
makefx audio ${first} batch "prompt" --name <name> --count <2-8> --output-dir <dir> [--collection <id>] [--space <id>]
|
|
9923
10374
|
${first === "music" ? "\nProvider selection:\n --provider <elevenlabs|lyria> Music provider (default: server default)\n" : ""}
|
|
9924
10375
|
${first === "speech" || first === "dialogue" ? "\nModel selection:\n --model <model_id> ElevenLabs model (default: eleven_v3)\n" : ""}
|
|
9925
10376
|
${first === "speech" || first === "dialogue" ? "\nVoice selection:\n --voice <voice_id> Speech voice, or dialogue fallback voice\n --dialogue-voices <id,id,...> Dialogue voices ordered by first speaker appearance\n" : ""}
|
|
@@ -9929,31 +10380,31 @@ ${first === "speech" || first === "dialogue" ? "\nVoice selection:\n --voice <v
|
|
|
9929
10380
|
if (first === "generate") {
|
|
9930
10381
|
console.log(`
|
|
9931
10382
|
Usage:
|
|
9932
|
-
makefx audio generate "prompt" --name <name> --type <type> -o <file> [--space <id>]
|
|
10383
|
+
makefx audio generate "prompt" --name <name> --type <type> -o <file> [--collection <id>] [--space <id>]
|
|
9933
10384
|
|
|
9934
10385
|
Preferred mode form:
|
|
9935
|
-
makefx audio <${modes}> generate "prompt" --name <name> -o <file> [--space <id>]
|
|
10386
|
+
makefx audio <${modes}> generate "prompt" --name <name> -o <file> [--collection <id>] [--space <id>]
|
|
9936
10387
|
`);
|
|
9937
10388
|
return;
|
|
9938
10389
|
}
|
|
9939
10390
|
if (first === "batch") {
|
|
9940
10391
|
console.log(`
|
|
9941
10392
|
Usage:
|
|
9942
|
-
makefx audio batch "prompt" --name <name> --type <type> --count <2-8> --output-dir <dir> [--space <id>]
|
|
10393
|
+
makefx audio batch "prompt" --name <name> --type <type> --count <2-8> --output-dir <dir> [--collection <id>] [--space <id>]
|
|
9943
10394
|
|
|
9944
10395
|
Preferred mode form:
|
|
9945
|
-
makefx audio <${modes}> batch "prompt" --name <name> --count <2-8> --output-dir <dir> [--space <id>]
|
|
10396
|
+
makefx audio <${modes}> batch "prompt" --name <name> --count <2-8> --output-dir <dir> [--collection <id>] [--space <id>]
|
|
9946
10397
|
`);
|
|
9947
10398
|
return;
|
|
9948
10399
|
}
|
|
9949
10400
|
console.log(`
|
|
9950
10401
|
Usage:
|
|
9951
|
-
makefx audio <${modes}> generate "prompt" --name <name> -o <file> [--space <id>]
|
|
9952
|
-
makefx audio <${modes}> generate --input <file> --name <name> -o <file> [--space <id>]
|
|
9953
|
-
makefx audio <${modes}> generate --follow <variant_id> -o <file> [--space <id>]
|
|
9954
|
-
makefx audio <${modes}> batch "prompt" --name <name> --count <2-8> --output-dir <dir> [--space <id>]
|
|
10402
|
+
makefx audio <${modes}> generate "prompt" --name <name> -o <file> [--collection <id>] [--space <id>]
|
|
10403
|
+
makefx audio <${modes}> generate --input <file> --name <name> -o <file> [--collection <id>] [--space <id>]
|
|
10404
|
+
makefx audio <${modes}> generate --follow <variant_id> -o <file> [--collection <id>] [--space <id>]
|
|
10405
|
+
makefx audio <${modes}> batch "prompt" --name <name> --count <2-8> --output-dir <dir> [--collection <id>] [--space <id>]
|
|
9955
10406
|
makefx audio voices [--json]
|
|
9956
|
-
makefx audio music generate "prompt" --provider <elevenlabs|lyria> --name <name> -o <file> [--space <id>]
|
|
10407
|
+
makefx audio music generate "prompt" --provider <elevenlabs|lyria> --name <name> -o <file> [--collection <id>] [--space <id>]
|
|
9957
10408
|
|
|
9958
10409
|
Modes:
|
|
9959
10410
|
speech Spoken narration or voiceover
|
|
@@ -9969,11 +10420,12 @@ Model selection:
|
|
|
9969
10420
|
--model <model_id> ElevenLabs speech/dialogue model (default: eleven_v3)
|
|
9970
10421
|
|
|
9971
10422
|
Low-level compatibility:
|
|
9972
|
-
makefx audio generate "prompt" --name <name> --type <type> -o <file> [--space <id>]
|
|
9973
|
-
makefx audio batch "prompt" --name <name> --type <type> --count <2-8> --output-dir <dir> [--space <id>]
|
|
10423
|
+
makefx audio generate "prompt" --name <name> --type <type> -o <file> [--collection <id>] [--space <id>]
|
|
10424
|
+
makefx audio batch "prompt" --name <name> --type <type> --count <2-8> --output-dir <dir> [--collection <id>] [--space <id>]
|
|
9974
10425
|
|
|
9975
10426
|
Long runs:
|
|
9976
|
-
If the CLI stops waiting after a job has started,
|
|
10427
|
+
If the CLI stops waiting after a job has started, the job keeps running in Make Effects.
|
|
10428
|
+
Rerun the printed --follow command to resume the same variant instead of starting a duplicate.
|
|
9977
10429
|
`);
|
|
9978
10430
|
}
|
|
9979
10431
|
function printVideoHelp(positionals) {
|
|
@@ -9981,8 +10433,8 @@ function printVideoHelp(positionals) {
|
|
|
9981
10433
|
if (subcommand === "generate") {
|
|
9982
10434
|
console.log(`
|
|
9983
10435
|
Usage:
|
|
9984
|
-
makefx video generate "prompt" --name <name> --type <type> -o <file> [--model ${videoModelValues()}] [--first-frame <variant_or_file>] [--last-frame <variant_or_file>] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--space <id>]
|
|
9985
|
-
makefx video generate --follow <variant_id> -o <file> [--space <id>]
|
|
10436
|
+
makefx video generate "prompt" --name <name> --type <type> -o <file> [--model ${videoModelValues()}] [--first-frame <variant_or_file>] [--last-frame <variant_or_file>] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--collection <id>] [--space <id>]
|
|
10437
|
+
makefx video generate --follow <variant_id> -o <file> [--collection <id>] [--space <id>]
|
|
9986
10438
|
|
|
9987
10439
|
${videoCapabilityHelp()}
|
|
9988
10440
|
|
|
@@ -9990,15 +10442,16 @@ Audio:
|
|
|
9990
10442
|
Video defaults to generated audio. Current Veo models do not support --no-audio; the CLI rejects it before creating a job.
|
|
9991
10443
|
|
|
9992
10444
|
Long runs:
|
|
9993
|
-
If the CLI stops waiting after a job has started,
|
|
10445
|
+
If the CLI stops waiting after a job has started, the job keeps running in Make Effects.
|
|
10446
|
+
Rerun the printed --follow command to resume the same variant instead of starting a duplicate.
|
|
9994
10447
|
`);
|
|
9995
10448
|
return;
|
|
9996
10449
|
}
|
|
9997
10450
|
if (subcommand === "refine") {
|
|
9998
10451
|
console.log(`
|
|
9999
10452
|
Usage:
|
|
10000
|
-
makefx video refine --variant <variant_id> "prompt" -o <file> [--model ${videoModelValues()}] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--space <id>]
|
|
10001
|
-
makefx video refine --follow <variant_id> -o <file> [--space <id>]
|
|
10453
|
+
makefx video refine --variant <variant_id> "prompt" -o <file> [--model ${videoModelValues()}] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--collection <id>] [--space <id>]
|
|
10454
|
+
makefx video refine --follow <variant_id> -o <file> [--collection <id>] [--space <id>]
|
|
10002
10455
|
|
|
10003
10456
|
${videoCapabilityHelp()}
|
|
10004
10457
|
|
|
@@ -10006,16 +10459,17 @@ Audio:
|
|
|
10006
10459
|
Video defaults to generated audio. Current Veo models do not support --no-audio; the CLI rejects it before creating a job.
|
|
10007
10460
|
|
|
10008
10461
|
Long runs:
|
|
10009
|
-
If the CLI stops waiting after a job has started,
|
|
10462
|
+
If the CLI stops waiting after a job has started, the job keeps running in Make Effects.
|
|
10463
|
+
Rerun the printed --follow command to resume the same variant instead of starting a duplicate.
|
|
10010
10464
|
`);
|
|
10011
10465
|
return;
|
|
10012
10466
|
}
|
|
10013
10467
|
if (subcommand === "derive") {
|
|
10014
10468
|
console.log(`
|
|
10015
10469
|
Usage:
|
|
10016
|
-
makefx video derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--model ${videoModelValues()}] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--space <id>]
|
|
10017
|
-
makefx video derive --first-frame <variant_or_file> [--last-frame <variant_or_file>] --name <name> --type <type> "prompt" -o <file> [--model veo-3.1] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--space <id>]
|
|
10018
|
-
makefx video derive --follow <variant_id> -o <file> [--space <id>]
|
|
10470
|
+
makefx video derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--model ${videoModelValues()}] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--collection <id>] [--space <id>]
|
|
10471
|
+
makefx video derive --first-frame <variant_or_file> [--last-frame <variant_or_file>] --name <name> --type <type> "prompt" -o <file> [--model veo-3.1] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--collection <id>] [--space <id>]
|
|
10472
|
+
makefx video derive --follow <variant_id> -o <file> [--collection <id>] [--space <id>]
|
|
10019
10473
|
|
|
10020
10474
|
${videoCapabilityHelp()}
|
|
10021
10475
|
|
|
@@ -10023,17 +10477,18 @@ Audio:
|
|
|
10023
10477
|
Video defaults to generated audio. Current Veo models do not support --no-audio; the CLI rejects it before creating a job.
|
|
10024
10478
|
|
|
10025
10479
|
Long runs:
|
|
10026
|
-
If the CLI stops waiting after a job has started,
|
|
10480
|
+
If the CLI stops waiting after a job has started, the job keeps running in Make Effects.
|
|
10481
|
+
Rerun the printed --follow command to resume the same variant instead of starting a duplicate.
|
|
10027
10482
|
`);
|
|
10028
10483
|
return;
|
|
10029
10484
|
}
|
|
10030
10485
|
console.log(`
|
|
10031
10486
|
Usage:
|
|
10032
|
-
makefx video generate "prompt" --name <name> --type <type> -o <file> [--model ${videoModelValues()}] [--first-frame <variant_or_file>] [--last-frame <variant_or_file>] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--space <id>]
|
|
10033
|
-
makefx video generate --follow <variant_id> -o <file> [--space <id>]
|
|
10034
|
-
makefx video refine --variant <variant_id> "prompt" -o <file> [--model ${videoModelValues()}] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--space <id>]
|
|
10035
|
-
makefx video derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--model ${videoModelValues()}] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--space <id>]
|
|
10036
|
-
makefx video derive --first-frame <variant_or_file> [--last-frame <variant_or_file>] --name <name> --type <type> "prompt" -o <file> [--model veo-3.1] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--space <id>]
|
|
10487
|
+
makefx video generate "prompt" --name <name> --type <type> -o <file> [--model ${videoModelValues()}] [--first-frame <variant_or_file>] [--last-frame <variant_or_file>] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--collection <id>] [--space <id>]
|
|
10488
|
+
makefx video generate --follow <variant_id> -o <file> [--collection <id>] [--space <id>]
|
|
10489
|
+
makefx video refine --variant <variant_id> "prompt" -o <file> [--model ${videoModelValues()}] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--collection <id>] [--space <id>]
|
|
10490
|
+
makefx video derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--model ${videoModelValues()}] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--collection <id>] [--space <id>]
|
|
10491
|
+
makefx video derive --first-frame <variant_or_file> [--last-frame <variant_or_file>] --name <name> --type <type> "prompt" -o <file> [--model veo-3.1] [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--collection <id>] [--space <id>]
|
|
10037
10492
|
|
|
10038
10493
|
${videoCapabilityHelp()}
|
|
10039
10494
|
|
|
@@ -10041,7 +10496,8 @@ Audio:
|
|
|
10041
10496
|
Video defaults to generated audio. Current Veo models do not support --no-audio; the CLI rejects it before creating a job.
|
|
10042
10497
|
|
|
10043
10498
|
Long runs:
|
|
10044
|
-
If the CLI stops waiting after a job has started,
|
|
10499
|
+
If the CLI stops waiting after a job has started, the job keeps running in Make Effects.
|
|
10500
|
+
Rerun the printed --follow command to resume the same variant instead of starting a duplicate.
|
|
10045
10501
|
`);
|
|
10046
10502
|
}
|
|
10047
10503
|
function printRunsHelp() {
|
|
@@ -10091,6 +10547,26 @@ Usage:
|
|
|
10091
10547
|
makefx assets set-active <asset-id> <variant-id>
|
|
10092
10548
|
`);
|
|
10093
10549
|
}
|
|
10550
|
+
function printCollectionsHelp() {
|
|
10551
|
+
console.log(`
|
|
10552
|
+
Usage:
|
|
10553
|
+
makefx collections
|
|
10554
|
+
makefx collections --json
|
|
10555
|
+
makefx collections create "<name>" [--kind cast|backgrounds|scenes|thumbnails|maps|deliverables|custom]
|
|
10556
|
+
makefx collections delete <collection-id>
|
|
10557
|
+
makefx collections items <collection-id>
|
|
10558
|
+
makefx collections add-asset <collection-id> <asset-id> [--variant <variant-id>] [--role <role>]
|
|
10559
|
+
makefx collections add-variant <collection-id> <variant-id> [--role <role>]
|
|
10560
|
+
makefx collections remove <collection-id> <item-id>
|
|
10561
|
+
makefx collections reorder <collection-id> <item-id,item-id,...>
|
|
10562
|
+
|
|
10563
|
+
Options:
|
|
10564
|
+
--space <id> Target space ID; defaults from the initialized project
|
|
10565
|
+
--env <env> Environment (production|stage|local)
|
|
10566
|
+
--local Shortcut for --env local
|
|
10567
|
+
--json Print machine-readable output where supported
|
|
10568
|
+
`);
|
|
10569
|
+
}
|
|
10094
10570
|
function printUsageHelp() {
|
|
10095
10571
|
console.log(`
|
|
10096
10572
|
Usage:
|
|
@@ -10173,6 +10649,10 @@ async function dispatchCommand(command, parsed) {
|
|
|
10173
10649
|
case "assets":
|
|
10174
10650
|
await handleAssets(parsed);
|
|
10175
10651
|
break;
|
|
10652
|
+
case "collections":
|
|
10653
|
+
case "collection":
|
|
10654
|
+
await handleCollections(parsed);
|
|
10655
|
+
break;
|
|
10176
10656
|
case "usage":
|
|
10177
10657
|
await handleUsage(parsed);
|
|
10178
10658
|
break;
|