blitzreels 0.1.5 → 0.1.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 +41 -8
- package/dist/agent-context.d.ts +26 -1
- package/dist/agent-context.d.ts.map +1 -1
- package/dist/agent-context.js +45 -1
- package/dist/agent-context.js.map +1 -1
- package/dist/cli-command-routing.d.ts.map +1 -1
- package/dist/cli-command-routing.js +18 -3
- package/dist/cli-command-routing.js.map +1 -1
- package/dist/cli-errors.d.ts +3 -1
- package/dist/cli-errors.d.ts.map +1 -1
- package/dist/cli-errors.js +3 -1
- package/dist/cli-errors.js.map +1 -1
- package/dist/cli-presenter.d.ts +2 -1
- package/dist/cli-presenter.d.ts.map +1 -1
- package/dist/cli-presenter.js +75 -31
- package/dist/cli-presenter.js.map +1 -1
- package/dist/cli-runtime.d.ts +1 -2
- package/dist/cli-runtime.d.ts.map +1 -1
- package/dist/cli-runtime.js +20 -2
- package/dist/cli-runtime.js.map +1 -1
- package/dist/cli-types.d.ts +2 -1
- package/dist/cli-types.d.ts.map +1 -1
- package/dist/cli-value-parsers.d.ts +4 -4
- package/dist/cli-value-parsers.d.ts.map +1 -1
- package/dist/cli-value-parsers.js +11 -6
- package/dist/cli-value-parsers.js.map +1 -1
- package/dist/command-metadata.d.ts +9 -3
- package/dist/command-metadata.d.ts.map +1 -1
- package/dist/command-metadata.js +33 -4
- package/dist/command-metadata.js.map +1 -1
- package/dist/command-registry.d.ts.map +1 -1
- package/dist/command-registry.js +10 -0
- package/dist/command-registry.js.map +1 -1
- package/dist/commands/ai-edit.js +7 -5
- package/dist/commands/ai-edit.js.map +1 -1
- package/dist/commands/audio.d.ts +3 -3
- package/dist/commands/audio.d.ts.map +1 -1
- package/dist/commands/audio.js +5 -2
- package/dist/commands/audio.js.map +1 -1
- package/dist/commands/caption-dry-run.js +20 -0
- package/dist/commands/caption-dry-run.js.map +1 -1
- package/dist/commands/caption-selection.d.ts +2 -1
- package/dist/commands/caption-selection.d.ts.map +1 -1
- package/dist/commands/caption-style-flags.d.ts.map +1 -1
- package/dist/commands/caption-style-flags.js +58 -0
- package/dist/commands/caption-style-flags.js.map +1 -1
- package/dist/commands/captions-specs.d.ts.map +1 -1
- package/dist/commands/captions-specs.js +23 -1
- package/dist/commands/captions-specs.js.map +1 -1
- package/dist/commands/captions.js +23 -1
- package/dist/commands/captions.js.map +1 -1
- package/dist/commands/clip-runtime.d.ts +2 -5
- package/dist/commands/clip-runtime.d.ts.map +1 -1
- package/dist/commands/clip-runtime.js +36 -111
- package/dist/commands/clip-runtime.js.map +1 -1
- package/dist/commands/clips.d.ts +12 -5
- package/dist/commands/clips.d.ts.map +1 -1
- package/dist/commands/clips.js +466 -83
- package/dist/commands/clips.js.map +1 -1
- package/dist/commands/effects.d.ts.map +1 -1
- package/dist/commands/effects.js +6 -0
- package/dist/commands/effects.js.map +1 -1
- package/dist/commands/exports.d.ts +1 -8
- package/dist/commands/exports.d.ts.map +1 -1
- package/dist/commands/exports.js +69 -7
- package/dist/commands/exports.js.map +1 -1
- package/dist/commands/faceless.d.ts +44 -0
- package/dist/commands/faceless.d.ts.map +1 -0
- package/dist/commands/faceless.js +587 -0
- package/dist/commands/faceless.js.map +1 -0
- package/dist/commands/formats.d.ts +41 -0
- package/dist/commands/formats.d.ts.map +1 -0
- package/dist/commands/formats.js +140 -0
- package/dist/commands/formats.js.map +1 -0
- package/dist/commands/generation.d.ts +25 -0
- package/dist/commands/generation.d.ts.map +1 -0
- package/dist/commands/generation.js +494 -0
- package/dist/commands/generation.js.map +1 -0
- package/dist/commands/jobs.d.ts +20 -0
- package/dist/commands/jobs.d.ts.map +1 -0
- package/dist/commands/jobs.js +40 -0
- package/dist/commands/jobs.js.map +1 -0
- package/dist/commands/media-assets.d.ts.map +1 -1
- package/dist/commands/media-assets.js +81 -9
- package/dist/commands/media-assets.js.map +1 -1
- package/dist/commands/media-overlays.d.ts.map +1 -1
- package/dist/commands/media-overlays.js +50 -6
- package/dist/commands/media-overlays.js.map +1 -1
- package/dist/commands/media-runtime.js +19 -1
- package/dist/commands/media-runtime.js.map +1 -1
- package/dist/commands/onboarding.d.ts +51 -0
- package/dist/commands/onboarding.d.ts.map +1 -0
- package/dist/commands/onboarding.js +452 -0
- package/dist/commands/onboarding.js.map +1 -0
- package/dist/commands/project-read.d.ts.map +1 -1
- package/dist/commands/project-read.js +32 -3
- package/dist/commands/project-read.js.map +1 -1
- package/dist/commands/projects.d.ts +1 -6
- package/dist/commands/projects.d.ts.map +1 -1
- package/dist/commands/projects.js +24 -4
- package/dist/commands/projects.js.map +1 -1
- package/dist/commands/system.d.ts.map +1 -1
- package/dist/commands/system.js +56 -14
- package/dist/commands/system.js.map +1 -1
- package/dist/commands/text-overlay-spec.d.ts +6 -0
- package/dist/commands/text-overlay-spec.d.ts.map +1 -1
- package/dist/commands/text-overlay-spec.js +59 -0
- package/dist/commands/text-overlay-spec.js.map +1 -1
- package/dist/commands/text-overlays.d.ts +6 -0
- package/dist/commands/text-overlays.d.ts.map +1 -1
- package/dist/commands/text-overlays.js +74 -1
- package/dist/commands/text-overlays.js.map +1 -1
- package/dist/commands/timeline-runtime.d.ts +3 -0
- package/dist/commands/timeline-runtime.d.ts.map +1 -1
- package/dist/commands/timeline-runtime.js +102 -9
- package/dist/commands/timeline-runtime.js.map +1 -1
- package/dist/commands/timeline.d.ts +4 -0
- package/dist/commands/timeline.d.ts.map +1 -1
- package/dist/commands/timeline.js +119 -47
- package/dist/commands/timeline.js.map +1 -1
- package/dist/index.js +59 -3
- package/dist/index.js.map +1 -1
- package/dist/preview-first-edit.d.ts +3 -1
- package/dist/preview-first-edit.d.ts.map +1 -1
- package/dist/preview-first-edit.js +2 -2
- package/dist/preview-first-edit.js.map +1 -1
- package/dist/update-notifier.d.ts +2 -1
- package/dist/update-notifier.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { CliUsageError } from "../cli-errors.js";
|
|
2
|
+
import { commandSpec } from "../command-metadata.js";
|
|
3
|
+
export const FORMATS_COMMAND_SPECS = [
|
|
4
|
+
commandSpec({
|
|
5
|
+
command: ["formats", "run"],
|
|
6
|
+
usage: "blitzreels formats run --format video-model-benchmark --prompt TEXT " +
|
|
7
|
+
"--left-model wan-2.1 --right-model krea-wan-14b-t2v --confirm-cost " +
|
|
8
|
+
"[--duration-seconds 5] [--brand-label blitzreels] " +
|
|
9
|
+
"[--idempotency-key KEY] [--json]",
|
|
10
|
+
description: "Create a branded split-screen project from the same prompt and two text-to-video models.",
|
|
11
|
+
flags: [
|
|
12
|
+
{
|
|
13
|
+
name: "format",
|
|
14
|
+
enum: ["video-model-benchmark"],
|
|
15
|
+
required: true,
|
|
16
|
+
},
|
|
17
|
+
{ name: "prompt", required: true },
|
|
18
|
+
{ name: "left-model", required: true },
|
|
19
|
+
{ name: "right-model", required: true },
|
|
20
|
+
{ name: "duration-seconds", type: "number", default: 5 },
|
|
21
|
+
"left-label",
|
|
22
|
+
"right-label",
|
|
23
|
+
{ name: "brand-label", default: "blitzreels" },
|
|
24
|
+
"project-name",
|
|
25
|
+
{
|
|
26
|
+
name: "confirm-cost",
|
|
27
|
+
type: "boolean",
|
|
28
|
+
description: "Confirm that both model generations consume AI credits.",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: "idempotency-key",
|
|
32
|
+
description: "Stable retry key; reuse only with identical inputs.",
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
mutates: true,
|
|
36
|
+
dryRunSupported: true,
|
|
37
|
+
}),
|
|
38
|
+
];
|
|
39
|
+
function buildBenchmarkInput({ flags, helpers, }) {
|
|
40
|
+
const format = helpers.requireStringFlag({ flags, name: "format" });
|
|
41
|
+
if (format !== "video-model-benchmark") {
|
|
42
|
+
throw new CliUsageError({
|
|
43
|
+
code: "invalid_flag_value",
|
|
44
|
+
message: "--format must be video-model-benchmark.",
|
|
45
|
+
usage: FORMATS_COMMAND_SPECS[0]?.usage,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
prompt: helpers.requireStringFlag({ flags, name: "prompt" }),
|
|
50
|
+
leftModel: helpers.requireStringFlag({
|
|
51
|
+
flags,
|
|
52
|
+
name: "left-model",
|
|
53
|
+
}),
|
|
54
|
+
rightModel: helpers.requireStringFlag({
|
|
55
|
+
flags,
|
|
56
|
+
name: "right-model",
|
|
57
|
+
}),
|
|
58
|
+
durationSeconds: helpers.getNumberFlag({ flags, name: "duration-seconds" }) ?? 5,
|
|
59
|
+
leftLabel: helpers.getStringFlag({ flags, name: "left-label" }) ?? null,
|
|
60
|
+
rightLabel: helpers.getStringFlag({ flags, name: "right-label" }) ?? null,
|
|
61
|
+
brandLabel: helpers.getStringFlag({ flags, name: "brand-label" }) ?? "blitzreels",
|
|
62
|
+
projectName: helpers.getStringFlag({ flags, name: "project-name" }) ?? null,
|
|
63
|
+
idempotencyKey: helpers.getStringFlag({
|
|
64
|
+
flags,
|
|
65
|
+
name: "idempotency-key",
|
|
66
|
+
}),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export function createFormatsCommandOperation({ helpers, }) {
|
|
70
|
+
return {
|
|
71
|
+
name: "formats",
|
|
72
|
+
matches: ({ command }) => command[0] === "formats",
|
|
73
|
+
handle: async ({ context }) => {
|
|
74
|
+
if (context.args.command[1] !== "run") {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
if (!helpers.getBooleanFlag({
|
|
78
|
+
flags: context.args.flags,
|
|
79
|
+
name: "confirm-cost",
|
|
80
|
+
})) {
|
|
81
|
+
throw new CliUsageError({
|
|
82
|
+
code: "cost_confirmation_required",
|
|
83
|
+
message: "This format runs two paid video generations. Re-run with --confirm-cost.",
|
|
84
|
+
usage: FORMATS_COMMAND_SPECS[0]?.usage,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
const result = await context.client.formats.runVideoModelBenchmark(buildBenchmarkInput({ flags: context.args.flags, helpers }));
|
|
88
|
+
helpers.printResult({
|
|
89
|
+
json: context.json,
|
|
90
|
+
value: result,
|
|
91
|
+
human: [
|
|
92
|
+
`Benchmark queued: ${result.job_id}`,
|
|
93
|
+
`Project: ${result.project_id}`,
|
|
94
|
+
`Models: ${result.plan.left.label} vs ${result.plan.right.label}`,
|
|
95
|
+
`Estimated credits: ${result.estimated_credits}`,
|
|
96
|
+
`Poll: blitzreels jobs get --job-id ${result.job_id} --json`,
|
|
97
|
+
],
|
|
98
|
+
fields: undefined,
|
|
99
|
+
});
|
|
100
|
+
return true;
|
|
101
|
+
},
|
|
102
|
+
buildDryRun: ({ context, spec }) => {
|
|
103
|
+
const input = buildBenchmarkInput({
|
|
104
|
+
flags: context.args.flags,
|
|
105
|
+
helpers,
|
|
106
|
+
});
|
|
107
|
+
return helpers.dryRunRequest({
|
|
108
|
+
spec,
|
|
109
|
+
method: "POST",
|
|
110
|
+
path: "/formats/video-model-benchmark/runs",
|
|
111
|
+
body: {
|
|
112
|
+
prompt: input.prompt,
|
|
113
|
+
left_model: input.leftModel,
|
|
114
|
+
right_model: input.rightModel,
|
|
115
|
+
duration_seconds: input.durationSeconds,
|
|
116
|
+
left_label: input.leftLabel,
|
|
117
|
+
right_label: input.rightLabel,
|
|
118
|
+
brand_label: input.brandLabel,
|
|
119
|
+
project_name: input.projectName,
|
|
120
|
+
},
|
|
121
|
+
followUpRequests: [
|
|
122
|
+
{
|
|
123
|
+
method: "GET",
|
|
124
|
+
path: "/jobs/{job_id}",
|
|
125
|
+
body: undefined,
|
|
126
|
+
reason: "Poll until the benchmark and media processing are terminal.",
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
method: "GET",
|
|
130
|
+
path: "/projects/{project_id}/context?mode=timeline",
|
|
131
|
+
body: undefined,
|
|
132
|
+
reason: "Inspect the composed split-screen project before export.",
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
notes: ["This operation consumes credits for two video generations."],
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=formats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formats.js","sourceRoot":"","sources":["../../src/commands/formats.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type CommandSpec } from "../command-metadata.js";
|
|
2
|
+
import type { DryRunPreview } from "../preview-first-edit.js";
|
|
3
|
+
import type { CommandOperation } from "./command-operation.js";
|
|
4
|
+
export declare const GENERATION_COMMAND_SPECS: CommandSpec[];
|
|
5
|
+
type GenerationCommandHelpers = {
|
|
6
|
+
dryRunRequest: (params: {
|
|
7
|
+
spec: CommandSpec;
|
|
8
|
+
method: string;
|
|
9
|
+
path: string;
|
|
10
|
+
body: unknown;
|
|
11
|
+
followUpRequests: DryRunPreview["follow_up_requests"] | undefined;
|
|
12
|
+
notes: string[] | undefined;
|
|
13
|
+
}) => DryRunPreview;
|
|
14
|
+
printResult: (params: {
|
|
15
|
+
json: boolean;
|
|
16
|
+
value: unknown;
|
|
17
|
+
human: string[];
|
|
18
|
+
fields: string[] | undefined;
|
|
19
|
+
}) => void;
|
|
20
|
+
};
|
|
21
|
+
export declare function createGenerationCommandOperation({ helpers, }: {
|
|
22
|
+
helpers: GenerationCommandHelpers;
|
|
23
|
+
}): CommandOperation;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=generation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generation.d.ts","sourceRoot":"","sources":["../../src/commands/generation.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,WAAW,EAAe,MAAM,wBAAwB,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAgC/D,eAAO,MAAM,wBAAwB,EAAE,WAAW,EA2HjD,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,aAAa,EAAE,CAAC,MAAM,EAAE;QACtB,IAAI,EAAE,WAAW,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,OAAO,CAAC;QACd,gBAAgB,EAAE,aAAa,CAAC,oBAAoB,CAAC,GAAG,SAAS,CAAC;QAClE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;KAC7B,KAAK,aAAa,CAAC;IACpB,WAAW,EAAE,CAAC,MAAM,EAAE;QACpB,IAAI,EAAE,OAAO,CAAC;QACd,KAAK,EAAE,OAAO,CAAC;QACf,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;KAC9B,KAAK,IAAI,CAAC;CACZ,CAAC;AAwVF,wBAAgB,gCAAgC,CAAC,EAC/C,OAAO,GACR,EAAE;IACD,OAAO,EAAE,wBAAwB,CAAC;CACnC,GAAG,gBAAgB,CAmEnB"}
|
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
import { readFile, stat, writeFile } from "node:fs/promises";
|
|
2
|
+
import { basename, extname, resolve } from "node:path";
|
|
3
|
+
import { CliUsageError } from "../cli-errors.js";
|
|
4
|
+
import { commandSpec } from "../command-metadata.js";
|
|
5
|
+
const GENERATION_COMMANDS = [
|
|
6
|
+
["generate", "images"],
|
|
7
|
+
["generate", "videos"],
|
|
8
|
+
["generate", "voiceovers"],
|
|
9
|
+
["generate", "music"],
|
|
10
|
+
["generate", "sounds"],
|
|
11
|
+
["generate", "faceless"],
|
|
12
|
+
];
|
|
13
|
+
const SHARED_FLAGS = [
|
|
14
|
+
{
|
|
15
|
+
name: "options",
|
|
16
|
+
type: "boolean",
|
|
17
|
+
description: "Print current options without creating a generation job.",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: "no-wait",
|
|
21
|
+
type: "boolean",
|
|
22
|
+
description: "Return the queued Generation Job receipt immediately.",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "idempotency-key",
|
|
26
|
+
description: "Stable retry key; reuse only with identical inputs.",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: "output",
|
|
30
|
+
description: "Write the generated asset to this local path after waiting.",
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
export const GENERATION_COMMAND_SPECS = [
|
|
34
|
+
commandSpec({
|
|
35
|
+
command: ["generate", "images"],
|
|
36
|
+
usage: "blitzreels generate images --prompt TEXT [--model ID] " +
|
|
37
|
+
"[--aspect-ratio 1:1] [--reference FILE] " +
|
|
38
|
+
"[--reference-asset-id ID] [--output FILE] [--no-wait] [--json]",
|
|
39
|
+
description: "Generate one image as a durable workspace asset.",
|
|
40
|
+
flags: [
|
|
41
|
+
"prompt",
|
|
42
|
+
"model",
|
|
43
|
+
"aspect-ratio",
|
|
44
|
+
"reference",
|
|
45
|
+
"reference-asset-id",
|
|
46
|
+
"folder-id",
|
|
47
|
+
...SHARED_FLAGS,
|
|
48
|
+
],
|
|
49
|
+
mutates: true,
|
|
50
|
+
dryRunSupported: true,
|
|
51
|
+
}),
|
|
52
|
+
commandSpec({
|
|
53
|
+
command: ["generate", "videos"],
|
|
54
|
+
usage: "blitzreels generate videos --prompt TEXT [--model ID] " +
|
|
55
|
+
"[--duration 5] [--aspect-ratio 9:16] [--source-image FILE] " +
|
|
56
|
+
"[--source-asset-id ID] [--reference FILE] [--output FILE] " +
|
|
57
|
+
"[--no-wait] [--json]",
|
|
58
|
+
description: "Generate one video as a durable workspace asset.",
|
|
59
|
+
flags: [
|
|
60
|
+
"prompt",
|
|
61
|
+
"model",
|
|
62
|
+
{ name: "duration", type: "number" },
|
|
63
|
+
"aspect-ratio",
|
|
64
|
+
"source-image",
|
|
65
|
+
"source-asset-id",
|
|
66
|
+
"reference",
|
|
67
|
+
"reference-asset-id",
|
|
68
|
+
{ name: "generate-audio", type: "boolean" },
|
|
69
|
+
"negative-prompt",
|
|
70
|
+
{ name: "seed", type: "number" },
|
|
71
|
+
"folder-id",
|
|
72
|
+
...SHARED_FLAGS,
|
|
73
|
+
],
|
|
74
|
+
mutates: true,
|
|
75
|
+
dryRunSupported: true,
|
|
76
|
+
}),
|
|
77
|
+
commandSpec({
|
|
78
|
+
command: ["generate", "voiceovers"],
|
|
79
|
+
usage: "blitzreels generate voiceovers --text TEXT [--voice-id ID] " +
|
|
80
|
+
"[--voice-style neutral] [--speed 1] [--output FILE] " +
|
|
81
|
+
"[--no-wait] [--json]",
|
|
82
|
+
description: "Generate one voiceover as a durable workspace asset.",
|
|
83
|
+
flags: [
|
|
84
|
+
"text",
|
|
85
|
+
"voice-id",
|
|
86
|
+
"voice-style",
|
|
87
|
+
{ name: "speed", type: "number" },
|
|
88
|
+
...SHARED_FLAGS,
|
|
89
|
+
],
|
|
90
|
+
mutates: true,
|
|
91
|
+
dryRunSupported: true,
|
|
92
|
+
}),
|
|
93
|
+
commandSpec({
|
|
94
|
+
command: ["generate", "music"],
|
|
95
|
+
usage: "blitzreels generate music [--prompt TEXT] [--mood neutral] " +
|
|
96
|
+
"[--duration 30] [--output FILE] [--no-wait] [--json]",
|
|
97
|
+
description: "Generate one music track as a durable workspace asset.",
|
|
98
|
+
flags: [
|
|
99
|
+
"prompt",
|
|
100
|
+
"mood",
|
|
101
|
+
{ name: "duration", type: "number" },
|
|
102
|
+
...SHARED_FLAGS,
|
|
103
|
+
],
|
|
104
|
+
mutates: true,
|
|
105
|
+
dryRunSupported: true,
|
|
106
|
+
}),
|
|
107
|
+
commandSpec({
|
|
108
|
+
command: ["generate", "sounds"],
|
|
109
|
+
usage: "blitzreels generate sounds --prompt TEXT [--duration 2] [--loop] " +
|
|
110
|
+
"[--prompt-influence 0.5] [--output FILE] [--no-wait] [--json]",
|
|
111
|
+
description: "Generate one sound as a durable workspace asset.",
|
|
112
|
+
flags: [
|
|
113
|
+
"prompt",
|
|
114
|
+
{ name: "duration", type: "number" },
|
|
115
|
+
{ name: "loop", type: "boolean" },
|
|
116
|
+
{ name: "prompt-influence", type: "number" },
|
|
117
|
+
...SHARED_FLAGS,
|
|
118
|
+
],
|
|
119
|
+
mutates: true,
|
|
120
|
+
dryRunSupported: true,
|
|
121
|
+
}),
|
|
122
|
+
commandSpec({
|
|
123
|
+
command: ["generate", "faceless"],
|
|
124
|
+
usage: "blitzreels generate faceless (--script TEXT | --script-file FILE) " +
|
|
125
|
+
"[--project-name NAME] [--duration 45] [--visual-style STYLE] " +
|
|
126
|
+
"[--voice-id ID] [--background-music] [--sound-effects] " +
|
|
127
|
+
"[--no-wait] [--json]",
|
|
128
|
+
description: "Create a Faceless Video project and its first reviewable plan.",
|
|
129
|
+
flags: [
|
|
130
|
+
"script",
|
|
131
|
+
"script-file",
|
|
132
|
+
"project-name",
|
|
133
|
+
{ name: "duration", type: "number" },
|
|
134
|
+
"visual-style",
|
|
135
|
+
"planner-model",
|
|
136
|
+
"image-model",
|
|
137
|
+
"video-model",
|
|
138
|
+
{ name: "voiceover", type: "boolean" },
|
|
139
|
+
"voice-id",
|
|
140
|
+
{ name: "captions", type: "boolean" },
|
|
141
|
+
"caption-style-id",
|
|
142
|
+
{ name: "background-music", type: "boolean" },
|
|
143
|
+
{ name: "sound-effects", type: "boolean" },
|
|
144
|
+
...SHARED_FLAGS.filter((flag) => flag.name !== "output"),
|
|
145
|
+
],
|
|
146
|
+
mutates: true,
|
|
147
|
+
dryRunSupported: true,
|
|
148
|
+
}),
|
|
149
|
+
];
|
|
150
|
+
function kindForCommand({ command, }) {
|
|
151
|
+
switch (command[1]) {
|
|
152
|
+
case "images":
|
|
153
|
+
return "image";
|
|
154
|
+
case "videos":
|
|
155
|
+
return "video";
|
|
156
|
+
case "voiceovers":
|
|
157
|
+
return "voiceover";
|
|
158
|
+
case "music":
|
|
159
|
+
return "music";
|
|
160
|
+
case "sounds":
|
|
161
|
+
return "sound";
|
|
162
|
+
case "faceless":
|
|
163
|
+
return "faceless";
|
|
164
|
+
default:
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function splitRepeatedFlag({ value }) {
|
|
169
|
+
return value
|
|
170
|
+
? value
|
|
171
|
+
.split(",")
|
|
172
|
+
.map((item) => item.trim())
|
|
173
|
+
.filter(Boolean)
|
|
174
|
+
: [];
|
|
175
|
+
}
|
|
176
|
+
function requireFlag({ context, name, }) {
|
|
177
|
+
const value = context.invocation.flags.string({ name });
|
|
178
|
+
if (!value) {
|
|
179
|
+
throw new CliUsageError({
|
|
180
|
+
code: "missing_required_flag",
|
|
181
|
+
message: `Missing required --${name}.`,
|
|
182
|
+
usage: GENERATION_COMMAND_SPECS.find((spec) => spec.command[1] === context.args.command[1])?.usage,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
return value;
|
|
186
|
+
}
|
|
187
|
+
async function stageLocalFile({ context, filePath, }) {
|
|
188
|
+
const absolutePath = resolve(filePath);
|
|
189
|
+
const fileStats = await stat(absolutePath);
|
|
190
|
+
if (!fileStats.isFile()) {
|
|
191
|
+
throw new Error(`Not a file: ${absolutePath}`);
|
|
192
|
+
}
|
|
193
|
+
const fileName = basename(absolutePath);
|
|
194
|
+
const contentType = inferContentType({ filePath: absolutePath });
|
|
195
|
+
const upload = await context.client.media.initUpload({
|
|
196
|
+
fileName,
|
|
197
|
+
contentType,
|
|
198
|
+
fileSizeBytes: fileStats.size,
|
|
199
|
+
});
|
|
200
|
+
const bytes = await readFile(absolutePath);
|
|
201
|
+
const response = await fetch(upload.upload_url, {
|
|
202
|
+
method: "PUT",
|
|
203
|
+
headers: { "Content-Type": contentType },
|
|
204
|
+
body: new Blob([new Uint8Array(bytes)], { type: contentType }),
|
|
205
|
+
});
|
|
206
|
+
if (!response.ok) {
|
|
207
|
+
throw new Error(`Upload failed with ${response.status}: ${await response.text()}`);
|
|
208
|
+
}
|
|
209
|
+
const asset = await context.client.media.finalizeUpload({
|
|
210
|
+
storageKey: upload.storage_key,
|
|
211
|
+
fileName,
|
|
212
|
+
contentType,
|
|
213
|
+
fileSizeBytes: fileStats.size,
|
|
214
|
+
autoProcessEnabled: false,
|
|
215
|
+
autoTranscribe: false,
|
|
216
|
+
autoDescribeAfterTranscribe: false,
|
|
217
|
+
autoSuggestShorts: false,
|
|
218
|
+
});
|
|
219
|
+
return asset.id;
|
|
220
|
+
}
|
|
221
|
+
function inferContentType({ filePath }) {
|
|
222
|
+
switch (extname(filePath).toLowerCase()) {
|
|
223
|
+
case ".png":
|
|
224
|
+
return "image/png";
|
|
225
|
+
case ".jpg":
|
|
226
|
+
case ".jpeg":
|
|
227
|
+
return "image/jpeg";
|
|
228
|
+
case ".webp":
|
|
229
|
+
return "image/webp";
|
|
230
|
+
default:
|
|
231
|
+
throw new Error(`Unsupported generation reference file: ${filePath}`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
async function stageReferences({ context, }) {
|
|
235
|
+
const assetIds = splitRepeatedFlag({
|
|
236
|
+
value: context.invocation.flags.string({ name: "reference-asset-id" }),
|
|
237
|
+
});
|
|
238
|
+
const localPaths = splitRepeatedFlag({
|
|
239
|
+
value: context.invocation.flags.string({ name: "reference" }),
|
|
240
|
+
});
|
|
241
|
+
for (const localPath of localPaths) {
|
|
242
|
+
assetIds.push(await stageLocalFile({ context, filePath: localPath }));
|
|
243
|
+
}
|
|
244
|
+
return assetIds;
|
|
245
|
+
}
|
|
246
|
+
async function submitGeneration({ context, kind, }) {
|
|
247
|
+
const flags = context.invocation.flags;
|
|
248
|
+
const idempotencyKey = flags.string({ name: "idempotency-key" });
|
|
249
|
+
if (kind === "image") {
|
|
250
|
+
return context.client.generation.images({
|
|
251
|
+
prompt: requireFlag({ context, name: "prompt" }),
|
|
252
|
+
model: flags.string({ name: "model" }),
|
|
253
|
+
aspectRatio: flags.string({ name: "aspect-ratio" }),
|
|
254
|
+
referenceAssetIds: await stageReferences({ context }),
|
|
255
|
+
folderId: flags.string({ name: "folder-id" }) ?? null,
|
|
256
|
+
idempotencyKey,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
if (kind === "video") {
|
|
260
|
+
const localSource = flags.string({ name: "source-image" });
|
|
261
|
+
const sourceAssetId = localSource
|
|
262
|
+
? await stageLocalFile({ context, filePath: localSource })
|
|
263
|
+
: (flags.string({ name: "source-asset-id" }) ?? null);
|
|
264
|
+
return context.client.generation.videos({
|
|
265
|
+
prompt: requireFlag({ context, name: "prompt" }),
|
|
266
|
+
model: flags.string({ name: "model" }),
|
|
267
|
+
durationSeconds: flags.number({ name: "duration" }),
|
|
268
|
+
aspectRatio: flags.string({ name: "aspect-ratio" }),
|
|
269
|
+
sourceAssetId,
|
|
270
|
+
referenceAssetIds: await stageReferences({ context }),
|
|
271
|
+
generateAudio: flags.optionalBoolean({ name: "generate-audio" }),
|
|
272
|
+
negativePrompt: flags.string({ name: "negative-prompt" }) ?? null,
|
|
273
|
+
seed: flags.number({ name: "seed" }) ?? null,
|
|
274
|
+
folderId: flags.string({ name: "folder-id" }) ?? null,
|
|
275
|
+
idempotencyKey,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
if (kind === "voiceover") {
|
|
279
|
+
return context.client.generation.voiceovers({
|
|
280
|
+
text: requireFlag({ context, name: "text" }),
|
|
281
|
+
voiceId: flags.string({ name: "voice-id" }),
|
|
282
|
+
voiceStyle: flags.string({ name: "voice-style" }),
|
|
283
|
+
speed: flags.number({ name: "speed" }),
|
|
284
|
+
idempotencyKey,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
if (kind === "music") {
|
|
288
|
+
return context.client.generation.music({
|
|
289
|
+
prompt: flags.string({ name: "prompt" }),
|
|
290
|
+
mood: flags.string({ name: "mood" }),
|
|
291
|
+
durationSeconds: flags.number({ name: "duration" }),
|
|
292
|
+
idempotencyKey,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
if (kind === "sound") {
|
|
296
|
+
return context.client.generation.sounds({
|
|
297
|
+
prompt: requireFlag({ context, name: "prompt" }),
|
|
298
|
+
durationSeconds: flags.number({ name: "duration" }),
|
|
299
|
+
loop: flags.optionalBoolean({ name: "loop" }),
|
|
300
|
+
promptInfluence: flags.number({ name: "prompt-influence" }),
|
|
301
|
+
idempotencyKey,
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
const scriptFile = flags.string({ name: "script-file" });
|
|
305
|
+
const script = scriptFile
|
|
306
|
+
? await readFile(resolve(scriptFile), "utf8")
|
|
307
|
+
: requireFlag({ context, name: "script" });
|
|
308
|
+
return context.client.generation.faceless({
|
|
309
|
+
script,
|
|
310
|
+
projectName: flags.string({ name: "project-name" }),
|
|
311
|
+
targetDurationSeconds: flags.number({ name: "duration" }),
|
|
312
|
+
visualStyle: flags.string({ name: "visual-style" }),
|
|
313
|
+
plannerModelId: flags.string({ name: "planner-model" }),
|
|
314
|
+
imageModelId: flags.string({ name: "image-model" }),
|
|
315
|
+
videoModel: flags.string({ name: "video-model" }),
|
|
316
|
+
generateVoiceover: flags.optionalBoolean({ name: "voiceover" }),
|
|
317
|
+
voiceId: flags.string({ name: "voice-id" }),
|
|
318
|
+
includeCaptions: flags.optionalBoolean({ name: "captions" }),
|
|
319
|
+
captionStyleId: flags.string({ name: "caption-style-id" }),
|
|
320
|
+
generateBackgroundMusic: flags.optionalBoolean({
|
|
321
|
+
name: "background-music",
|
|
322
|
+
}),
|
|
323
|
+
generateSoundEffects: flags.optionalBoolean({ name: "sound-effects" }),
|
|
324
|
+
idempotencyKey,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
async function waitAndMaybeDownload({ context, receipt, }) {
|
|
328
|
+
const job = await context.client.generation.wait({
|
|
329
|
+
jobId: receipt.job_id,
|
|
330
|
+
intervalMs: 3000,
|
|
331
|
+
timeoutMs: 30 * 60 * 1000,
|
|
332
|
+
});
|
|
333
|
+
const output = context.invocation.flags.string({ name: "output" });
|
|
334
|
+
if (!output) {
|
|
335
|
+
return job;
|
|
336
|
+
}
|
|
337
|
+
const outputPath = resolve(output);
|
|
338
|
+
await writeFile(outputPath, Buffer.from(await context.client.generation.download({ jobId: receipt.job_id })));
|
|
339
|
+
return { ...job, output_path: outputPath };
|
|
340
|
+
}
|
|
341
|
+
function humanResult({ result, }) {
|
|
342
|
+
return [
|
|
343
|
+
`Generation job: ${result.job_id}`,
|
|
344
|
+
`Status: ${result.status}`,
|
|
345
|
+
`Project: ${result.project_id ?? "none"}`,
|
|
346
|
+
`Asset: ${result.media_id ?? "pending"}`,
|
|
347
|
+
...("download_url" in result && result.download_url
|
|
348
|
+
? [`Download: ${result.download_url}`]
|
|
349
|
+
: []),
|
|
350
|
+
];
|
|
351
|
+
}
|
|
352
|
+
function buildGenerationDryRunBody({ context, kind, }) {
|
|
353
|
+
const flags = context.invocation.flags;
|
|
354
|
+
const referenceAssetIds = splitRepeatedFlag({
|
|
355
|
+
value: flags.string({ name: "reference-asset-id" }),
|
|
356
|
+
});
|
|
357
|
+
const stagedReferences = splitRepeatedFlag({
|
|
358
|
+
value: flags.string({ name: "reference" }),
|
|
359
|
+
}).map((filePath) => `<staged:${resolve(filePath)}>`);
|
|
360
|
+
if (kind === "image") {
|
|
361
|
+
return {
|
|
362
|
+
prompt: flags.string({ name: "prompt" }),
|
|
363
|
+
model: flags.string({ name: "model" }),
|
|
364
|
+
aspect_ratio: flags.string({ name: "aspect-ratio" }),
|
|
365
|
+
reference_asset_ids: [...referenceAssetIds, ...stagedReferences],
|
|
366
|
+
folder_id: flags.string({ name: "folder-id" }),
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
if (kind === "video") {
|
|
370
|
+
const sourceImage = flags.string({ name: "source-image" });
|
|
371
|
+
return {
|
|
372
|
+
prompt: flags.string({ name: "prompt" }),
|
|
373
|
+
model: flags.string({ name: "model" }),
|
|
374
|
+
duration_seconds: flags.number({ name: "duration" }),
|
|
375
|
+
aspect_ratio: flags.string({ name: "aspect-ratio" }),
|
|
376
|
+
source_asset_id: sourceImage
|
|
377
|
+
? `<staged:${resolve(sourceImage)}>`
|
|
378
|
+
: flags.string({ name: "source-asset-id" }),
|
|
379
|
+
reference_asset_ids: [...referenceAssetIds, ...stagedReferences],
|
|
380
|
+
generate_audio: flags.optionalBoolean({ name: "generate-audio" }),
|
|
381
|
+
negative_prompt: flags.string({ name: "negative-prompt" }),
|
|
382
|
+
seed: flags.number({ name: "seed" }),
|
|
383
|
+
folder_id: flags.string({ name: "folder-id" }),
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
if (kind === "voiceover") {
|
|
387
|
+
return {
|
|
388
|
+
text: flags.string({ name: "text" }),
|
|
389
|
+
voice_id: flags.string({ name: "voice-id" }),
|
|
390
|
+
voice_style: flags.string({ name: "voice-style" }),
|
|
391
|
+
speed: flags.number({ name: "speed" }),
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
if (kind === "music") {
|
|
395
|
+
return {
|
|
396
|
+
prompt: flags.string({ name: "prompt" }),
|
|
397
|
+
mood: flags.string({ name: "mood" }),
|
|
398
|
+
duration_seconds: flags.number({ name: "duration" }),
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
if (kind === "sound") {
|
|
402
|
+
return {
|
|
403
|
+
prompt: flags.string({ name: "prompt" }),
|
|
404
|
+
duration_seconds: flags.number({ name: "duration" }),
|
|
405
|
+
loop: flags.optionalBoolean({ name: "loop" }),
|
|
406
|
+
prompt_influence: flags.number({ name: "prompt-influence" }),
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
return {
|
|
410
|
+
script: flags.string({ name: "script" }) ??
|
|
411
|
+
(flags.string({ name: "script-file" })
|
|
412
|
+
? `<file:${resolve(flags.string({ name: "script-file" }))}>`
|
|
413
|
+
: undefined),
|
|
414
|
+
project_name: flags.string({ name: "project-name" }),
|
|
415
|
+
target_duration_seconds: flags.number({ name: "duration" }),
|
|
416
|
+
visual_style: flags.string({ name: "visual-style" }),
|
|
417
|
+
planner_model_id: flags.string({ name: "planner-model" }),
|
|
418
|
+
image_model_id: flags.string({ name: "image-model" }),
|
|
419
|
+
video_model: flags.string({ name: "video-model" }),
|
|
420
|
+
generate_voiceover: flags.optionalBoolean({ name: "voiceover" }),
|
|
421
|
+
voice_id: flags.string({ name: "voice-id" }),
|
|
422
|
+
include_captions: flags.optionalBoolean({ name: "captions" }),
|
|
423
|
+
caption_style_id: flags.string({ name: "caption-style-id" }),
|
|
424
|
+
generate_background_music: flags.optionalBoolean({
|
|
425
|
+
name: "background-music",
|
|
426
|
+
}),
|
|
427
|
+
generate_sound_effects: flags.optionalBoolean({ name: "sound-effects" }),
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
export function createGenerationCommandOperation({ helpers, }) {
|
|
431
|
+
return {
|
|
432
|
+
name: "generation",
|
|
433
|
+
matches: ({ command }) => GENERATION_COMMANDS.some((candidate) => candidate[0] === command[0] && candidate[1] === command[1]),
|
|
434
|
+
handle: async ({ context }) => {
|
|
435
|
+
const kind = kindForCommand({ command: context.args.command });
|
|
436
|
+
if (kind === null) {
|
|
437
|
+
return false;
|
|
438
|
+
}
|
|
439
|
+
if (context.invocation.flags.boolean({ name: "options" })) {
|
|
440
|
+
const options = await context.client.generation.options({ kind });
|
|
441
|
+
helpers.printResult({
|
|
442
|
+
json: context.json,
|
|
443
|
+
value: options,
|
|
444
|
+
human: [JSON.stringify(options, null, 2)],
|
|
445
|
+
fields: context.fields,
|
|
446
|
+
});
|
|
447
|
+
return true;
|
|
448
|
+
}
|
|
449
|
+
const receipt = await submitGeneration({ context, kind });
|
|
450
|
+
const result = context.invocation.flags.boolean({ name: "no-wait" })
|
|
451
|
+
? receipt
|
|
452
|
+
: await waitAndMaybeDownload({ context, receipt });
|
|
453
|
+
helpers.printResult({
|
|
454
|
+
json: context.json,
|
|
455
|
+
value: result,
|
|
456
|
+
human: humanResult({ result }),
|
|
457
|
+
fields: context.fields,
|
|
458
|
+
});
|
|
459
|
+
return true;
|
|
460
|
+
},
|
|
461
|
+
buildDryRun: ({ context, spec }) => {
|
|
462
|
+
const kind = kindForCommand({ command: context.args.command });
|
|
463
|
+
if (kind === null) {
|
|
464
|
+
return undefined;
|
|
465
|
+
}
|
|
466
|
+
if (context.invocation.flags.boolean({ name: "options" })) {
|
|
467
|
+
return helpers.dryRunRequest({
|
|
468
|
+
spec,
|
|
469
|
+
method: "GET",
|
|
470
|
+
path: `/generation-options/${kind}`,
|
|
471
|
+
body: undefined,
|
|
472
|
+
followUpRequests: undefined,
|
|
473
|
+
notes: ["No generation job or credit spend."],
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
return helpers.dryRunRequest({
|
|
477
|
+
spec,
|
|
478
|
+
method: "POST",
|
|
479
|
+
path: `/generate-${kind}`,
|
|
480
|
+
body: buildGenerationDryRunBody({ context, kind }),
|
|
481
|
+
followUpRequests: [
|
|
482
|
+
{
|
|
483
|
+
method: "GET",
|
|
484
|
+
path: "/generation-jobs/{job_id}",
|
|
485
|
+
body: undefined,
|
|
486
|
+
reason: "Poll until the generation is terminal.",
|
|
487
|
+
},
|
|
488
|
+
],
|
|
489
|
+
notes: ["Local reference files are staged before submission."],
|
|
490
|
+
});
|
|
491
|
+
},
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
//# sourceMappingURL=generation.js.map
|