makefx 0.1.1 → 0.1.3
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 +233 -172
- package/package.json +2 -2
package/README.md
CHANGED
package/makefx.mjs
CHANGED
|
@@ -808,65 +808,91 @@ function validateProjectConfig(config, configPath) {
|
|
|
808
808
|
* makefx spaces --id <space_id> Show details for a specific space
|
|
809
809
|
* makefx spaces create <name> Create a new space
|
|
810
810
|
*/
|
|
811
|
+
var defaultDeps$9 = {
|
|
812
|
+
loadConfig: loadStoredConfig,
|
|
813
|
+
resolveBaseUrl,
|
|
814
|
+
saveProjectConfig,
|
|
815
|
+
fetch,
|
|
816
|
+
print: console.log
|
|
817
|
+
};
|
|
811
818
|
async function handleSpaces(parsed) {
|
|
819
|
+
try {
|
|
820
|
+
await executeSpaces(parsed);
|
|
821
|
+
} catch (error) {
|
|
822
|
+
console.error("Error:", error instanceof Error ? error.message : error);
|
|
823
|
+
process$1.exitCode = 1;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
async function executeSpaces(parsed, deps = defaultDeps$9) {
|
|
812
827
|
const env = resolveCommandEnvironment(parsed);
|
|
813
828
|
const showDetails = parsed.options.details === "true";
|
|
814
829
|
const spaceId = parsed.options.id;
|
|
815
830
|
const subcommand = parsed.positionals[0];
|
|
816
831
|
const jsonOutput = parsed.options.json === "true";
|
|
817
|
-
const config = await
|
|
818
|
-
if (!config) {
|
|
819
|
-
|
|
820
|
-
console.error(`Run: ${loginCommandForEnvironment(env)}`);
|
|
821
|
-
process$1.exitCode = 1;
|
|
822
|
-
return;
|
|
823
|
-
}
|
|
824
|
-
if (config.token.expiresAt < Date.now()) {
|
|
825
|
-
console.error(`Token expired for ${env} environment.`);
|
|
826
|
-
console.error(`Run: ${loginCommandForEnvironment(env)}`);
|
|
827
|
-
process$1.exitCode = 1;
|
|
828
|
-
return;
|
|
829
|
-
}
|
|
830
|
-
const baseUrl = resolveBaseUrl(env);
|
|
831
|
-
const accessToken = config.token.accessToken;
|
|
832
|
+
const config = await deps.loadConfig(env);
|
|
833
|
+
if (!config) throw new Error(`Not logged in to ${env} environment. Run: ${loginCommandForEnvironment(env)}`);
|
|
834
|
+
if (config.token.expiresAt < Date.now()) throw new Error(`Token expired for ${env} environment. Run: ${loginCommandForEnvironment(env)}`);
|
|
832
835
|
if (env === "local") process$1.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
const project = parsed.options.init === "true" ? {
|
|
845
|
-
configPath: await saveProjectConfig({
|
|
846
|
-
environment: env,
|
|
847
|
-
spaceId: space.id
|
|
848
|
-
}),
|
|
836
|
+
const ctx = {
|
|
837
|
+
env,
|
|
838
|
+
baseUrl: deps.resolveBaseUrl(env),
|
|
839
|
+
accessToken: config.token.accessToken
|
|
840
|
+
};
|
|
841
|
+
if (subcommand === "create") {
|
|
842
|
+
const spaceName = parsed.positionals.slice(1).join(" ") || parsed.options.name;
|
|
843
|
+
if (!spaceName) throw new Error("Space name is required. Usage: makefx spaces create <name>");
|
|
844
|
+
const space = await createSpace(ctx, deps, spaceName);
|
|
845
|
+
const project = parsed.options.init === "true" ? {
|
|
846
|
+
configPath: await deps.saveProjectConfig({
|
|
849
847
|
environment: env,
|
|
850
848
|
spaceId: space.id
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
else
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
849
|
+
}),
|
|
850
|
+
environment: env,
|
|
851
|
+
spaceId: space.id
|
|
852
|
+
} : void 0;
|
|
853
|
+
if (jsonOutput) deps.print(JSON.stringify({
|
|
854
|
+
space,
|
|
855
|
+
project
|
|
856
|
+
}, null, 2));
|
|
857
|
+
else printCreatedSpace(space, ctx.env, project?.configPath, deps.print);
|
|
858
|
+
return {
|
|
859
|
+
type: "create",
|
|
860
|
+
space,
|
|
861
|
+
project
|
|
862
|
+
};
|
|
863
863
|
}
|
|
864
|
+
if (spaceId) {
|
|
865
|
+
const details = await getSpaceDetails(ctx, deps, spaceId);
|
|
866
|
+
if (jsonOutput) deps.print(JSON.stringify(details, null, 2));
|
|
867
|
+
else printSpaceDetails(details, deps.print);
|
|
868
|
+
return {
|
|
869
|
+
type: "show",
|
|
870
|
+
space: details.space,
|
|
871
|
+
assets: details.assets
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
if (showDetails) {
|
|
875
|
+
const spaces = await listSpaceSummaries(ctx, deps);
|
|
876
|
+
if (jsonOutput) deps.print(JSON.stringify(spaces, null, 2));
|
|
877
|
+
else printSpaceSummaries(spaces, deps.print);
|
|
878
|
+
return {
|
|
879
|
+
type: "details",
|
|
880
|
+
spaces
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
const spaces = await fetchSpaces(ctx, deps);
|
|
884
|
+
if (jsonOutput) deps.print(JSON.stringify(spaces, null, 2));
|
|
885
|
+
else printSpaces(spaces, deps.print);
|
|
886
|
+
return {
|
|
887
|
+
type: "list",
|
|
888
|
+
spaces
|
|
889
|
+
};
|
|
864
890
|
}
|
|
865
|
-
async function createSpace(
|
|
866
|
-
const response = await fetch(`${baseUrl}/api/spaces`, {
|
|
891
|
+
async function createSpace(ctx, deps, name) {
|
|
892
|
+
const response = await deps.fetch(`${ctx.baseUrl}/api/spaces`, {
|
|
867
893
|
method: "POST",
|
|
868
894
|
headers: {
|
|
869
|
-
"Authorization": `Bearer ${accessToken}`,
|
|
895
|
+
"Authorization": `Bearer ${ctx.accessToken}`,
|
|
870
896
|
"Content-Type": "application/json"
|
|
871
897
|
},
|
|
872
898
|
body: JSON.stringify({ name })
|
|
@@ -877,83 +903,82 @@ async function createSpace(baseUrl, accessToken, name) {
|
|
|
877
903
|
}
|
|
878
904
|
return (await response.json()).space;
|
|
879
905
|
}
|
|
880
|
-
function printCreatedSpace(space, env, configPath) {
|
|
906
|
+
function printCreatedSpace(space, env, configPath, print) {
|
|
881
907
|
const envFlag = env === "production" ? "" : env === "local" ? " --local" : ` --env ${env}`;
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
if (configPath)
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
}
|
|
892
|
-
async function
|
|
893
|
-
const response = await fetch(`${baseUrl}/api/spaces`, { headers: {
|
|
894
|
-
"Authorization": `Bearer ${accessToken}`,
|
|
908
|
+
print(`\nSpace created successfully!\n`);
|
|
909
|
+
print(` ID: ${space.id}`);
|
|
910
|
+
print(` Name: ${space.name}`);
|
|
911
|
+
print(` Role: ${space.role}`);
|
|
912
|
+
if (configPath) print(` Config: ${configPath}`);
|
|
913
|
+
print(`\nTo bind this directory:`);
|
|
914
|
+
print(` makefx init --space ${space.id}${envFlag}`);
|
|
915
|
+
print(`\nTo listen for events:`);
|
|
916
|
+
print(` makefx listen --space ${space.id}${envFlag}`);
|
|
917
|
+
}
|
|
918
|
+
async function fetchSpaces(ctx, deps) {
|
|
919
|
+
const response = await deps.fetch(`${ctx.baseUrl}/api/spaces`, { headers: {
|
|
920
|
+
"Authorization": `Bearer ${ctx.accessToken}`,
|
|
895
921
|
"Content-Type": "application/json"
|
|
896
922
|
} });
|
|
897
923
|
if (!response.ok) throw new Error(`Failed to fetch spaces: ${response.status}`);
|
|
898
|
-
|
|
924
|
+
return (await response.json()).spaces;
|
|
925
|
+
}
|
|
926
|
+
function printSpaces(spaces, print) {
|
|
899
927
|
if (spaces.length === 0) {
|
|
900
|
-
|
|
928
|
+
print("No spaces found.");
|
|
901
929
|
return;
|
|
902
930
|
}
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
for (const space of spaces)
|
|
907
|
-
|
|
908
|
-
|
|
931
|
+
print(`\nFound ${spaces.length} space(s):\n`);
|
|
932
|
+
print("ID".padEnd(38) + "Name".padEnd(30) + "Role");
|
|
933
|
+
print("-".repeat(80));
|
|
934
|
+
for (const space of spaces) print(space.id.padEnd(38) + truncatePad(space.name, 30) + space.role);
|
|
935
|
+
print(`\nFor details: makefx spaces --details`);
|
|
936
|
+
print(`For a specific space: makefx spaces --id <space_id>`);
|
|
909
937
|
}
|
|
910
|
-
async function
|
|
911
|
-
const
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
938
|
+
async function listSpaceSummaries(ctx, deps) {
|
|
939
|
+
const spaces = await fetchSpaces(ctx, deps);
|
|
940
|
+
const summaries = [];
|
|
941
|
+
for (const space of spaces) {
|
|
942
|
+
const assets = await fetchSpaceAssets(ctx, deps, space.id);
|
|
943
|
+
summaries.push({
|
|
944
|
+
space,
|
|
945
|
+
assetCount: assets.length,
|
|
946
|
+
assetSummary: summarizeAssets(assets)
|
|
947
|
+
});
|
|
948
|
+
}
|
|
949
|
+
return summaries;
|
|
950
|
+
}
|
|
951
|
+
function printSpaceSummaries(summaries, print) {
|
|
952
|
+
if (summaries.length === 0) {
|
|
953
|
+
print("No spaces found.");
|
|
919
954
|
return;
|
|
920
955
|
}
|
|
921
|
-
|
|
922
|
-
for (const
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
if (assetsResponse.ok) {
|
|
930
|
-
const assets = (await assetsResponse.json()).assets;
|
|
931
|
-
assetCount = assets.length;
|
|
932
|
-
if (assets.length > 0) {
|
|
933
|
-
const byType = /* @__PURE__ */ new Map();
|
|
934
|
-
for (const asset of assets) {
|
|
935
|
-
const type = asset.type || "unknown";
|
|
936
|
-
byType.set(type, (byType.get(type) || 0) + 1);
|
|
937
|
-
}
|
|
938
|
-
const typeParts = [];
|
|
939
|
-
for (const [type, count] of byType) typeParts.push(`${count} ${type}`);
|
|
940
|
-
assetSummary = typeParts.join(", ");
|
|
941
|
-
const firstNames = assets.slice(0, 3).map((a) => a.name);
|
|
942
|
-
if (assets.length > 3) firstNames.push(`+${assets.length - 3} more`);
|
|
943
|
-
assetSummary += ` (${firstNames.join(", ")})`;
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
console.log(`━━━ ${space.name} ━━━`);
|
|
947
|
-
console.log(` ID: ${space.id}`);
|
|
948
|
-
console.log(` Role: ${space.role}`);
|
|
949
|
-
console.log(` Assets: ${assetCount}`);
|
|
950
|
-
if (assetSummary) console.log(` Content: ${assetSummary}`);
|
|
951
|
-
console.log("");
|
|
956
|
+
print(`\nFetching details for ${summaries.length} space(s)...\n`);
|
|
957
|
+
for (const summary of summaries) {
|
|
958
|
+
print(`━━━ ${summary.space.name} ━━━`);
|
|
959
|
+
print(` ID: ${summary.space.id}`);
|
|
960
|
+
print(` Role: ${summary.space.role}`);
|
|
961
|
+
print(` Assets: ${summary.assetCount}`);
|
|
962
|
+
if (summary.assetSummary) print(` Content: ${summary.assetSummary}`);
|
|
963
|
+
print("");
|
|
952
964
|
}
|
|
953
965
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
966
|
+
function summarizeAssets(assets) {
|
|
967
|
+
if (assets.length === 0) return "";
|
|
968
|
+
const byType = /* @__PURE__ */ new Map();
|
|
969
|
+
for (const asset of assets) {
|
|
970
|
+
const type = asset.type || "unknown";
|
|
971
|
+
byType.set(type, (byType.get(type) || 0) + 1);
|
|
972
|
+
}
|
|
973
|
+
const typeParts = [];
|
|
974
|
+
for (const [type, count] of byType) typeParts.push(`${count} ${type}`);
|
|
975
|
+
const firstNames = assets.slice(0, 3).map((a) => a.name);
|
|
976
|
+
if (assets.length > 3) firstNames.push(`+${assets.length - 3} more`);
|
|
977
|
+
return `${typeParts.join(", ")} (${firstNames.join(", ")})`;
|
|
978
|
+
}
|
|
979
|
+
async function getSpaceDetails(ctx, deps, spaceId) {
|
|
980
|
+
const spaceResponse = await deps.fetch(`${ctx.baseUrl}/api/spaces/${spaceId}`, { headers: {
|
|
981
|
+
"Authorization": `Bearer ${ctx.accessToken}`,
|
|
957
982
|
"Content-Type": "application/json"
|
|
958
983
|
} });
|
|
959
984
|
if (!spaceResponse.ok) {
|
|
@@ -961,18 +986,28 @@ async function showSpaceDetails(baseUrl, accessToken, spaceId) {
|
|
|
961
986
|
if (spaceResponse.status === 404) throw new Error(`Space not found: ${spaceId}`);
|
|
962
987
|
throw new Error(`Failed to fetch space: ${spaceResponse.status}`);
|
|
963
988
|
}
|
|
964
|
-
const
|
|
965
|
-
const
|
|
966
|
-
|
|
989
|
+
const spaceData = await spaceResponse.json();
|
|
990
|
+
const assets = await fetchSpaceAssets(ctx, deps, spaceId);
|
|
991
|
+
return {
|
|
992
|
+
space: spaceData.space,
|
|
993
|
+
assets
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
async function fetchSpaceAssets(ctx, deps, spaceId) {
|
|
997
|
+
const assetsResponse = await deps.fetch(`${ctx.baseUrl}/api/spaces/${spaceId}/assets`, { headers: {
|
|
998
|
+
"Authorization": `Bearer ${ctx.accessToken}`,
|
|
967
999
|
"Content-Type": "application/json"
|
|
968
1000
|
} });
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1001
|
+
if (assetsResponse.ok) return (await assetsResponse.json()).assets;
|
|
1002
|
+
throw new Error(`Failed to fetch assets for space ${spaceId}: ${assetsResponse.status}`);
|
|
1003
|
+
}
|
|
1004
|
+
function printSpaceDetails(details, print) {
|
|
1005
|
+
const { space, assets } = details;
|
|
1006
|
+
print(`\n━━━ ${space.name} ━━━`);
|
|
1007
|
+
print(`ID: ${space.id}`);
|
|
1008
|
+
print(`Assets: ${assets.length}\n`);
|
|
974
1009
|
if (assets.length === 0) {
|
|
975
|
-
|
|
1010
|
+
print("(No assets in this space)");
|
|
976
1011
|
return;
|
|
977
1012
|
}
|
|
978
1013
|
const byType = /* @__PURE__ */ new Map();
|
|
@@ -982,16 +1017,15 @@ async function showSpaceDetails(baseUrl, accessToken, spaceId) {
|
|
|
982
1017
|
byType.get(type).push(asset);
|
|
983
1018
|
}
|
|
984
1019
|
for (const [type, typeAssets] of byType) {
|
|
985
|
-
|
|
1020
|
+
print(`${type.charAt(0).toUpperCase() + type.slice(1)}s (${typeAssets.length}):`);
|
|
986
1021
|
for (const asset of typeAssets) {
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
console.log(` ID: ${asset.id}`);
|
|
1022
|
+
print(` ${asset.active_variant_id ? "✓" : "○"} ${asset.name}`);
|
|
1023
|
+
print(` ID: ${asset.id}`);
|
|
990
1024
|
}
|
|
991
|
-
|
|
1025
|
+
print("");
|
|
992
1026
|
}
|
|
993
|
-
|
|
994
|
-
|
|
1027
|
+
print(`\nTo start a chat session with this space:`);
|
|
1028
|
+
print(` makefx chat send "What's in this space?" --space ${space.id} --state ./test/${space.name.toLowerCase().replace(/\s+/g, "-")}.json`);
|
|
995
1029
|
}
|
|
996
1030
|
function truncatePad(str, width) {
|
|
997
1031
|
if (str.length > width - 2) return str.slice(0, width - 3) + ".. ";
|
|
@@ -21263,6 +21297,7 @@ var VIDEO_GENERATION_TIERS = [
|
|
|
21263
21297
|
"fast",
|
|
21264
21298
|
"lite"
|
|
21265
21299
|
];
|
|
21300
|
+
var VIDEO_GENERATION_AUDIO_TOGGLE_MODELS = [];
|
|
21266
21301
|
var VIDEO_GENERATION_RESOLUTIONS_BY_TIER = {
|
|
21267
21302
|
generate: VIDEO_GENERATION_RESOLUTIONS,
|
|
21268
21303
|
fast: VIDEO_GENERATION_RESOLUTIONS,
|
|
@@ -21272,6 +21307,11 @@ var DEFAULT_VIDEO_GENERATION_TIER = "generate";
|
|
|
21272
21307
|
function normalizeVideoGenerationAspectRatio(value) {
|
|
21273
21308
|
return VIDEO_GENERATION_ASPECT_RATIOS.includes(value) ? value : void 0;
|
|
21274
21309
|
}
|
|
21310
|
+
var VIDEO_GENERATION_TIER_MODELS = {
|
|
21311
|
+
generate: "veo-3.1-generate-preview",
|
|
21312
|
+
fast: "veo-3.1-fast-generate-preview",
|
|
21313
|
+
lite: "veo-3.1-lite-generate-preview"
|
|
21314
|
+
};
|
|
21275
21315
|
function normalizeVideoGenerationResolution(value) {
|
|
21276
21316
|
return VIDEO_GENERATION_RESOLUTIONS.includes(value) ? value : void 0;
|
|
21277
21317
|
}
|
|
@@ -21282,12 +21322,18 @@ function normalizeVideoGenerationDurationSeconds(value) {
|
|
|
21282
21322
|
function normalizeVideoGenerationTier(value) {
|
|
21283
21323
|
return VIDEO_GENERATION_TIERS.includes(value) ? value : void 0;
|
|
21284
21324
|
}
|
|
21325
|
+
function getVideoGenerationModelForTier(tier = DEFAULT_VIDEO_GENERATION_TIER) {
|
|
21326
|
+
return VIDEO_GENERATION_TIER_MODELS[tier];
|
|
21327
|
+
}
|
|
21285
21328
|
function getVideoGenerationResolutionsForTier(tier = DEFAULT_VIDEO_GENERATION_TIER) {
|
|
21286
21329
|
return VIDEO_GENERATION_RESOLUTIONS_BY_TIER[tier];
|
|
21287
21330
|
}
|
|
21288
21331
|
function isVideoGenerationResolutionSupportedForTier(resolution, tier = DEFAULT_VIDEO_GENERATION_TIER) {
|
|
21289
21332
|
return VIDEO_GENERATION_RESOLUTIONS_BY_TIER[tier].includes(resolution);
|
|
21290
21333
|
}
|
|
21334
|
+
function doesVideoGenerationModelSupportAudioToggle(model) {
|
|
21335
|
+
return VIDEO_GENERATION_AUDIO_TOGGLE_MODELS.includes(model);
|
|
21336
|
+
}
|
|
21291
21337
|
//#endregion
|
|
21292
21338
|
//#region src/shared/imageGenerationOptions.ts
|
|
21293
21339
|
var IMAGE_MODEL_SELECTIONS = ["pro", "flash"];
|
|
@@ -21594,9 +21640,9 @@ async function executeForgeCommand(command, parsed, deps = defaultDeps$6, option
|
|
|
21594
21640
|
try {
|
|
21595
21641
|
await client.connect();
|
|
21596
21642
|
switch (command) {
|
|
21597
|
-
case "generate": return await executeGenerate(parsed, ctx, client, deps, mediaKind);
|
|
21643
|
+
case "generate": return await executeGenerate(parsed, ctx, client, deps, mediaKind, { audioMode: options.audioMode });
|
|
21598
21644
|
case "refine": return await executeRefine(parsed, ctx, client, deps, mediaKind);
|
|
21599
|
-
case "derive": return await executeDerive(parsed, ctx, client, deps, mediaKind);
|
|
21645
|
+
case "derive": return await executeDerive(parsed, ctx, client, deps, mediaKind, { audioMode: options.audioMode });
|
|
21600
21646
|
case "batch": return await executeBatch(parsed, ctx, client, deps, mediaKind, saveBatchManifest);
|
|
21601
21647
|
}
|
|
21602
21648
|
} finally {
|
|
@@ -21612,7 +21658,8 @@ async function executeAudioCommand(command, parsed, deps = defaultDeps$6, option
|
|
|
21612
21658
|
if (parsed.options.input && command !== "generate") throw new Error("Audio --input is only supported with generate");
|
|
21613
21659
|
return executeForgeCommand(command, await prepareAudioParsedArgs(parsed, options.mode), deps, {
|
|
21614
21660
|
mediaKind: audioProfile.mediaKind,
|
|
21615
|
-
saveBatchManifest: audioProfile.savesBatchManifest
|
|
21661
|
+
saveBatchManifest: audioProfile.savesBatchManifest,
|
|
21662
|
+
audioMode: options.mode
|
|
21616
21663
|
});
|
|
21617
21664
|
}
|
|
21618
21665
|
async function executeVideoCommand(command, parsed, deps = defaultDeps$6) {
|
|
@@ -21635,12 +21682,17 @@ async function prepareAudioParsedArgs(parsed, mode) {
|
|
|
21635
21682
|
const input = await readFile(options.input, "utf8");
|
|
21636
21683
|
positionals.push(input);
|
|
21637
21684
|
}
|
|
21685
|
+
if (!options.follow) validateAudioModeRequiredVoiceOptions(options, effectiveMode);
|
|
21638
21686
|
return {
|
|
21639
21687
|
options,
|
|
21640
21688
|
positionals
|
|
21641
21689
|
};
|
|
21642
21690
|
}
|
|
21643
|
-
|
|
21691
|
+
function validateAudioModeRequiredVoiceOptions(options, mode) {
|
|
21692
|
+
if (mode === "speech" && !normalizeCliOption(options.voice)) throw new Error("Speech generation requires --voice <voice_id>. Run: makefx audio voices");
|
|
21693
|
+
if (mode === "dialogue" && !normalizeCliOption(options["dialogue-voices"] ?? options.dialogueVoices)) throw new Error("Dialogue generation requires --dialogue-voices <voice_id,voice_id>. Run: makefx audio voices");
|
|
21694
|
+
}
|
|
21695
|
+
async function executeGenerate(parsed, ctx, client, deps, mediaKind, followOptions = {}) {
|
|
21644
21696
|
const prompt = getPrompt(parsed, "generate");
|
|
21645
21697
|
const outputPath = getOutputPath$1(parsed);
|
|
21646
21698
|
const name = requireOption(parsed, "name");
|
|
@@ -21671,7 +21723,7 @@ async function executeGenerate(parsed, ctx, client, deps, mediaKind) {
|
|
|
21671
21723
|
...musicProvider ? { musicProvider } : {},
|
|
21672
21724
|
...videoAudioOptions,
|
|
21673
21725
|
...videoOptions,
|
|
21674
|
-
onStarted: (started) => printFollowHint(started, ctx, outputPath, "generate", mediaKind)
|
|
21726
|
+
onStarted: (started) => printFollowHint(started, ctx, outputPath, "generate", mediaKind, followOptions)
|
|
21675
21727
|
});
|
|
21676
21728
|
const productionRecord = await placeProductionRecordFromScene({
|
|
21677
21729
|
command: "generate",
|
|
@@ -21773,7 +21825,7 @@ async function executeRefine(parsed, ctx, client, deps, mediaKind) {
|
|
|
21773
21825
|
printResult(result, outputPath, ctx, manifestPath, productionRecord);
|
|
21774
21826
|
return result;
|
|
21775
21827
|
}
|
|
21776
|
-
async function executeDerive(parsed, ctx, client, deps, mediaKind) {
|
|
21828
|
+
async function executeDerive(parsed, ctx, client, deps, mediaKind, followOptions = {}) {
|
|
21777
21829
|
const prompt = getPrompt(parsed, "derive");
|
|
21778
21830
|
const outputPath = getOutputPath$1(parsed);
|
|
21779
21831
|
const name = requireOption(parsed, "name");
|
|
@@ -21804,7 +21856,7 @@ async function executeDerive(parsed, ctx, client, deps, mediaKind) {
|
|
|
21804
21856
|
mediaKind,
|
|
21805
21857
|
...videoAudioOptions,
|
|
21806
21858
|
...videoOptions,
|
|
21807
|
-
onStarted: (started) => printFollowHint(started, ctx, outputPath, "derive", mediaKind)
|
|
21859
|
+
onStarted: (started) => printFollowHint(started, ctx, outputPath, "derive", mediaKind, followOptions)
|
|
21808
21860
|
});
|
|
21809
21861
|
const productionRecord = await placeProductionRecordFromScene({
|
|
21810
21862
|
command: "derive",
|
|
@@ -22227,16 +22279,17 @@ function printResult(result, outputPath, ctx, manifestPath, productionRecord) {
|
|
|
22227
22279
|
if (productionRecord) console.log(` Production: ${productionRecord.production_id} (${productionRecord.id})`);
|
|
22228
22280
|
console.log(` Web: ${ctx.baseUrl}/spaces/${ctx.spaceId}/assets/${variant.asset_id}`);
|
|
22229
22281
|
}
|
|
22230
|
-
function printFollowHint(started, ctx, outputPath, command, mediaKind) {
|
|
22282
|
+
function printFollowHint(started, ctx, outputPath, command, mediaKind, options = {}) {
|
|
22231
22283
|
console.log(` Started variant: ${started.jobId}`);
|
|
22232
|
-
console.log(` Follow: ${formatFollowCommand(started.jobId, outputPath, ctx, command, mediaKind)}`);
|
|
22284
|
+
console.log(` Follow: ${formatFollowCommand(started.jobId, outputPath, ctx, command, mediaKind, options)}`);
|
|
22233
22285
|
}
|
|
22234
|
-
function formatFollowCommand(variantId, outputPath, ctx, command, mediaKind) {
|
|
22286
|
+
function formatFollowCommand(variantId, outputPath, ctx, command, mediaKind, options = {}) {
|
|
22235
22287
|
const baseCommand = mediaKind === "audio" ? [
|
|
22236
22288
|
"makefx",
|
|
22237
22289
|
"audio",
|
|
22290
|
+
options.audioMode,
|
|
22238
22291
|
"generate"
|
|
22239
|
-
] : mediaKind === "video" ? [
|
|
22292
|
+
].filter((part) => Boolean(part)) : mediaKind === "video" ? [
|
|
22240
22293
|
"makefx",
|
|
22241
22294
|
"video",
|
|
22242
22295
|
command
|
|
@@ -22300,12 +22353,20 @@ function validateVideoAudioOptions(parsed, mediaKind) {
|
|
|
22300
22353
|
if (!(parsed.options.audio !== void 0 || parsed.options["no-audio"] !== void 0 || parsed.options.noAudio !== void 0)) return;
|
|
22301
22354
|
if (mediaKind !== "video") throw new Error("--audio and --no-audio are only supported for video generation");
|
|
22302
22355
|
if (parsed.options.audio !== void 0 && (parsed.options["no-audio"] !== void 0 || parsed.options.noAudio !== void 0)) throw new Error("Pass either --audio or --no-audio, not both");
|
|
22356
|
+
if (parsed.options["no-audio"] !== void 0 || parsed.options.noAudio !== void 0) {
|
|
22357
|
+
const tierValue = readOptionalOption(parsed, "tier", "tier") ?? readOptionalOption(parsed, "video-tier", "videoTier");
|
|
22358
|
+
const videoTier = tierValue === void 0 ? DEFAULT_VIDEO_GENERATION_TIER : normalizeVideoGenerationTier(tierValue);
|
|
22359
|
+
if (!videoTier) throw new Error("--tier must be generate, fast, or lite");
|
|
22360
|
+
const model = getVideoGenerationModelForTier(videoTier);
|
|
22361
|
+
if (!doesVideoGenerationModelSupportAudioToggle(model)) throw new Error(`${model} does not support --no-audio. Use the default audio-enabled output or omit the flag.`);
|
|
22362
|
+
}
|
|
22303
22363
|
}
|
|
22304
22364
|
function parseVideoAudioOptions(parsed, mediaKind) {
|
|
22305
|
-
if (mediaKind
|
|
22306
|
-
|
|
22307
|
-
|
|
22308
|
-
|
|
22365
|
+
if (mediaKind === "video") {
|
|
22366
|
+
if (parsed.options.audio !== void 0) return { generateAudio: true };
|
|
22367
|
+
if (parsed.options["no-audio"] !== void 0 || parsed.options.noAudio !== void 0) return { generateAudio: false };
|
|
22368
|
+
}
|
|
22369
|
+
return {};
|
|
22309
22370
|
}
|
|
22310
22371
|
function parseVideoGenerationOptions(parsed, mediaKind) {
|
|
22311
22372
|
const resolutionValue = readOptionalOption(parsed, "resolution", "resolution") ?? readOptionalOption(parsed, "video-resolution", "videoResolution");
|
|
@@ -22620,9 +22681,9 @@ Usage:
|
|
|
22620
22681
|
makefx audio <${modes}> batch "prompt" --name <name> --count <2-8> --output-dir <dir> [--space <id>]
|
|
22621
22682
|
makefx audio music generate "prompt" --provider lyria --name <name> -o <file> [--space <id>]
|
|
22622
22683
|
|
|
22623
|
-
Voice selection:
|
|
22684
|
+
Voice selection (run 'makefx audio voices' to list voice IDs):
|
|
22624
22685
|
makefx audio speech generate "text" --voice <voice_id> --name <name> -o <file>
|
|
22625
|
-
makefx audio dialogue generate --input script.txt --
|
|
22686
|
+
makefx audio dialogue generate --input script.txt --dialogue-voices <voice_id,voice_id> --name <name> -o <file>
|
|
22626
22687
|
|
|
22627
22688
|
Low-level compatibility:
|
|
22628
22689
|
makefx audio generate "prompt" --name <name> --type <type> -o <file> [--space <id>]
|
|
@@ -22656,11 +22717,11 @@ function printUsage$5() {
|
|
|
22656
22717
|
const resolutionByTier = VIDEO_GENERATION_TIERS.map((tier) => `${tier}: ${getVideoGenerationResolutionsForTier(tier).join(", ")}`).join("; ");
|
|
22657
22718
|
console.log(`
|
|
22658
22719
|
Usage:
|
|
22659
|
-
makefx video generate "prompt" --name <name> --type <type> -o <file> [--aspect ${aspectValues}] [--resolution ${resolutionValues}] [--duration ${durationValues}] [--tier ${tierValues}] [--audio
|
|
22720
|
+
makefx video generate "prompt" --name <name> --type <type> -o <file> [--aspect ${aspectValues}] [--resolution ${resolutionValues}] [--duration ${durationValues}] [--tier ${tierValues}] [--audio] [--space <id>]
|
|
22660
22721
|
makefx video generate --follow <variant_id> -o <file> [--space <id>]
|
|
22661
|
-
makefx video refine --variant <variant_id> "prompt" -o <file> [--aspect ${aspectValues}] [--resolution ${resolutionValues}] [--duration ${durationValues}] [--tier ${tierValues}] [--audio
|
|
22722
|
+
makefx video refine --variant <variant_id> "prompt" -o <file> [--aspect ${aspectValues}] [--resolution ${resolutionValues}] [--duration ${durationValues}] [--tier ${tierValues}] [--audio] [--space <id>]
|
|
22662
22723
|
makefx video refine --follow <variant_id> -o <file> [--space <id>]
|
|
22663
|
-
makefx video derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--aspect ${aspectValues}] [--resolution ${resolutionValues}] [--duration ${durationValues}] [--tier ${tierValues}] [--audio
|
|
22724
|
+
makefx video derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--aspect ${aspectValues}] [--resolution ${resolutionValues}] [--duration ${durationValues}] [--tier ${tierValues}] [--audio] [--space <id>]
|
|
22664
22725
|
makefx video derive --follow <variant_id> -o <file> [--space <id>]
|
|
22665
22726
|
|
|
22666
22727
|
Video:
|
|
@@ -22670,8 +22731,8 @@ Video:
|
|
|
22670
22731
|
--tier <tier> Veo model tier: ${tierValues}
|
|
22671
22732
|
|
|
22672
22733
|
Audio:
|
|
22673
|
-
--audio Request native synchronized Veo audio
|
|
22674
|
-
--no-audio
|
|
22734
|
+
--audio Request native synchronized Veo audio (default)
|
|
22735
|
+
--no-audio Not supported by current Veo models; rejected before a job is created.
|
|
22675
22736
|
|
|
22676
22737
|
Production metadata:
|
|
22677
22738
|
--scene-label <label> --timeline-start-ms <ms> --duration-ms <ms>
|
|
@@ -23565,9 +23626,11 @@ Options:
|
|
|
23565
23626
|
}
|
|
23566
23627
|
//#endregion
|
|
23567
23628
|
//#region src/cli/index.ts
|
|
23568
|
-
var CLI_VERSION = "0.1.
|
|
23629
|
+
var CLI_VERSION = "0.1.3+21fbf493922f";
|
|
23569
23630
|
async function main() {
|
|
23570
|
-
const
|
|
23631
|
+
const argv = process$1.argv.slice(2);
|
|
23632
|
+
if (argv[0] === "--") argv.shift();
|
|
23633
|
+
const [command, ...args] = argv;
|
|
23571
23634
|
if (command === "--version" || command === "version") {
|
|
23572
23635
|
console.log(CLI_VERSION);
|
|
23573
23636
|
return;
|
|
@@ -23760,8 +23823,9 @@ Billing (Polar.sh):
|
|
|
23760
23823
|
|
|
23761
23824
|
Spaces:
|
|
23762
23825
|
spaces List all spaces
|
|
23763
|
-
spaces --
|
|
23764
|
-
spaces --
|
|
23826
|
+
spaces --json List all spaces as JSON
|
|
23827
|
+
spaces --details [--json] List spaces with asset summaries
|
|
23828
|
+
spaces --id <id> [--json] Show details for a specific space
|
|
23765
23829
|
spaces create <name> Create a new space
|
|
23766
23830
|
|
|
23767
23831
|
Listen:
|
|
@@ -23787,10 +23851,10 @@ Audio:
|
|
|
23787
23851
|
audio sfx generate "prompt" --name <name> -o <file>
|
|
23788
23852
|
|
|
23789
23853
|
Video:
|
|
23790
|
-
video generate "prompt" --name <name> --type <type> -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio
|
|
23854
|
+
video generate "prompt" --name <name> --type <type> -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio]
|
|
23791
23855
|
video generate --follow <variant_id> -o <file>
|
|
23792
|
-
video refine --variant <variant_id> "prompt" -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio
|
|
23793
|
-
video derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio
|
|
23856
|
+
video refine --variant <variant_id> "prompt" -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio]
|
|
23857
|
+
video derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio]
|
|
23794
23858
|
|
|
23795
23859
|
Options:
|
|
23796
23860
|
--env <environment> Target environment (production|stage|local), default: production
|
|
@@ -23866,8 +23930,9 @@ function printSpacesHelp() {
|
|
|
23866
23930
|
console.log(`
|
|
23867
23931
|
Usage:
|
|
23868
23932
|
makefx spaces
|
|
23869
|
-
makefx spaces --
|
|
23870
|
-
makefx spaces --
|
|
23933
|
+
makefx spaces --json
|
|
23934
|
+
makefx spaces --details [--json]
|
|
23935
|
+
makefx spaces --id <space_id> [--json]
|
|
23871
23936
|
makefx spaces create <name>
|
|
23872
23937
|
makefx spaces create --name "My Space" [--init] [--json]
|
|
23873
23938
|
`);
|
|
@@ -24038,14 +24103,13 @@ function printVideoHelp(positionals) {
|
|
|
24038
24103
|
if (subcommand === "generate") {
|
|
24039
24104
|
console.log(`
|
|
24040
24105
|
Usage:
|
|
24041
|
-
makefx video generate "prompt" --name <name> --type <type> -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio
|
|
24106
|
+
makefx video generate "prompt" --name <name> --type <type> -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--space <id>]
|
|
24042
24107
|
makefx video generate --follow <variant_id> -o <file> [--space <id>]
|
|
24043
24108
|
|
|
24044
24109
|
${videoCapabilityHelp()}
|
|
24045
24110
|
|
|
24046
24111
|
Audio:
|
|
24047
|
-
--audio
|
|
24048
|
-
--no-audio Request a silent video (default)
|
|
24112
|
+
Video defaults to generated audio. Current Veo models do not support --no-audio; the CLI rejects it before creating a job.
|
|
24049
24113
|
|
|
24050
24114
|
Production metadata:
|
|
24051
24115
|
--scene-label <label> --timeline-start-ms <ms> --duration-ms <ms>
|
|
@@ -24056,14 +24120,13 @@ Production metadata:
|
|
|
24056
24120
|
if (subcommand === "refine") {
|
|
24057
24121
|
console.log(`
|
|
24058
24122
|
Usage:
|
|
24059
|
-
makefx video refine --variant <variant_id> "prompt" -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio
|
|
24123
|
+
makefx video refine --variant <variant_id> "prompt" -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--space <id>]
|
|
24060
24124
|
makefx video refine --follow <variant_id> -o <file> [--space <id>]
|
|
24061
24125
|
|
|
24062
24126
|
${videoCapabilityHelp()}
|
|
24063
24127
|
|
|
24064
24128
|
Audio:
|
|
24065
|
-
--audio
|
|
24066
|
-
--no-audio Request a silent video (default)
|
|
24129
|
+
Video defaults to generated audio. Current Veo models do not support --no-audio; the CLI rejects it before creating a job.
|
|
24067
24130
|
|
|
24068
24131
|
Production metadata:
|
|
24069
24132
|
--scene-label <label> --timeline-start-ms <ms> --duration-ms <ms>
|
|
@@ -24074,14 +24137,13 @@ Production metadata:
|
|
|
24074
24137
|
if (subcommand === "derive") {
|
|
24075
24138
|
console.log(`
|
|
24076
24139
|
Usage:
|
|
24077
|
-
makefx video derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio
|
|
24140
|
+
makefx video derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--space <id>]
|
|
24078
24141
|
makefx video derive --follow <variant_id> -o <file> [--space <id>]
|
|
24079
24142
|
|
|
24080
24143
|
${videoCapabilityHelp()}
|
|
24081
24144
|
|
|
24082
24145
|
Audio:
|
|
24083
|
-
--audio
|
|
24084
|
-
--no-audio Request a silent video (default)
|
|
24146
|
+
Video defaults to generated audio. Current Veo models do not support --no-audio; the CLI rejects it before creating a job.
|
|
24085
24147
|
|
|
24086
24148
|
Production metadata:
|
|
24087
24149
|
--scene-label <label> --timeline-start-ms <ms> --duration-ms <ms>
|
|
@@ -24091,16 +24153,15 @@ Production metadata:
|
|
|
24091
24153
|
}
|
|
24092
24154
|
console.log(`
|
|
24093
24155
|
Usage:
|
|
24094
|
-
makefx video generate "prompt" --name <name> --type <type> -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio
|
|
24156
|
+
makefx video generate "prompt" --name <name> --type <type> -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--space <id>]
|
|
24095
24157
|
makefx video generate --follow <variant_id> -o <file> [--space <id>]
|
|
24096
|
-
makefx video refine --variant <variant_id> "prompt" -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio
|
|
24097
|
-
makefx video derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio
|
|
24158
|
+
makefx video refine --variant <variant_id> "prompt" -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--space <id>]
|
|
24159
|
+
makefx video derive --refs <variant_or_file,variant_or_file> --name <name> --type <type> "prompt" -o <file> [--aspect ${videoAspectValues()}] [--resolution ${videoResolutionValues()}] [--duration ${videoDurationValues()}] [--tier ${videoTierValues()}] [--audio] [--space <id>]
|
|
24098
24160
|
|
|
24099
24161
|
${videoCapabilityHelp()}
|
|
24100
24162
|
|
|
24101
24163
|
Audio:
|
|
24102
|
-
--audio
|
|
24103
|
-
--no-audio Request a silent video (default)
|
|
24164
|
+
Video defaults to generated audio. Current Veo models do not support --no-audio; the CLI rejects it before creating a job.
|
|
24104
24165
|
|
|
24105
24166
|
Production metadata:
|
|
24106
24167
|
--scene-label <label> --timeline-start-ms <ms> --duration-ms <ms>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "makefx",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Command-line interface for AI-assisted game asset production with Make Effects.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"url": "git+https://github.com/krasnoperov/inventory.git"
|
|
10
10
|
},
|
|
11
11
|
"bin": {
|
|
12
|
-
"makefx": "
|
|
12
|
+
"makefx": "makefx.mjs"
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
15
|
"makefx.mjs",
|