makaron-cli 0.13.5 → 0.13.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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +16 -10
- package/bin/makaron.mjs +93 -52
- package/package.json +1 -1
- package/skills/makaron/SKILL.md +9 -5
package/README.md
CHANGED
|
@@ -98,7 +98,12 @@ npx makaron-cli chat --project auto --image photo.jpg --json -b "make it cinemat
|
|
|
98
98
|
npx makaron-cli chat --project auto --image img1.jpg --image img2.jpg --json -b "combine these"
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
`chat`
|
|
101
|
+
`chat` routes image and video models automatically, but you may select the Agent LLM with `--agent-model`. Accepted values are exactly `auto`, `gpt-5.6-terra`, `gpt-5.6-sol`, `gpt-5.6-luna`, `grok-4.5`, and `deepseek-v4-pro`; `auto` currently resolves to `gpt-5.6-terra`. This flag changes only the reasoning/tool-calling Agent LLM. The CLI still rejects `--image-model`, `--video-model`, and the legacy `--model` flag before starting a chat run, so image/video model names cannot be mistaken for Agent models.
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Explicit lower-cost Agent LLM for a controlled comparison
|
|
105
|
+
npx makaron-cli chat --project auto --agent-model deepseek-v4-pro --json -b "make a 20s badminton video"
|
|
106
|
+
```
|
|
102
107
|
|
|
103
108
|
Returns immediately:
|
|
104
109
|
```json
|
|
@@ -156,11 +161,10 @@ External source ranges can be added without uploading either the original video
|
|
|
156
161
|
```bash
|
|
157
162
|
npx makaron-cli project media add <projectId> \
|
|
158
163
|
--source-url "https://cdn.example.com/source.mp4" \
|
|
159
|
-
--start
|
|
160
|
-
--source-uri "dam://project/asset" \
|
|
164
|
+
--start 12.5 --end 19 \
|
|
161
165
|
--description "Racket frame molding"
|
|
162
166
|
|
|
163
|
-
# Batch form: a JSON array or {"
|
|
167
|
+
# Batch form: a JSON array or {"clips": [...]}
|
|
164
168
|
npx makaron-cli project media add <projectId> --input ranges.json --json
|
|
165
169
|
```
|
|
166
170
|
|
|
@@ -181,10 +185,12 @@ npx makaron-cli chat --project auto \
|
|
|
181
185
|
"Make a 30-second 9:16 TikTok with English VO and burned-in captions"
|
|
182
186
|
```
|
|
183
187
|
|
|
184
|
-
The manifest is a JSON array or `{ "title": "...", "
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
+
The manifest is a JSON array or `{ "title": "...", "clips": [...] }`. Every
|
|
189
|
+
clip contains exactly `source_url`, `start`, `end`, and `description`; the time
|
|
190
|
+
values are seconds and array order is edit order. It is validated before project
|
|
191
|
+
creation and supports up to 20 clips for one Makaron task. Batch planning remains
|
|
192
|
+
the upstream orchestrator's responsibility: convert each plan into one manifest
|
|
193
|
+
and start one independent Makaron task.
|
|
188
194
|
|
|
189
195
|
### Export editable Remotion compositions
|
|
190
196
|
|
|
@@ -341,7 +347,7 @@ npx makaron-cli video create --script "Shot 1 (15s): <<<image_1>>> and <<<image_
|
|
|
341
347
|
|
|
342
348
|
# 3b. Native SeeDance or MiniMax H3 text-to-video (no image required)
|
|
343
349
|
npx makaron-cli video create --script "Shot 1 (5s): A neon one-person studio wakes at dawn" --duration 5 --video-model seedance-fast --aspect 16:9
|
|
344
|
-
npx makaron-cli video create --script "Shot 1 (15s): A premium creative editor comes alive" --duration 15 --video-model minimax-h3 --
|
|
350
|
+
npx makaron-cli video create --script "Shot 1 (15s): A premium creative editor comes alive" --duration 15 --video-model minimax-h3 --aspect 16:9
|
|
345
351
|
|
|
346
352
|
# 3c. Edit a video from a local file or public URL
|
|
347
353
|
npx makaron-cli video create --script "make it funny" --video input.mp4 --duration 5 --video-model seedance-fast
|
|
@@ -357,7 +363,7 @@ For project/timeline video editing, use:
|
|
|
357
363
|
npx makaron-cli chat --project <id|auto> --video input.mp4 -b "make it funny"
|
|
358
364
|
```
|
|
359
365
|
|
|
360
|
-
Options for `video create`: `--script "..."`, `--script-file <path>`, `--image <url>` (repeatable, up to the selected model limit), `--video <file|url>` and `--audio <file|url>` (repeatable where supported), `--duration <seconds>`, `--aspect 9:16|16:9|1:1`, `--video-model seedance-fast|seedance-mini|seedance|seedance-2.5|kling|grok|google-omni|minimax-h3`, `--video-resolution auto|480p|720p|768p|1080p|2k|4k`. Default model is `seedance-fast`. SeeDance accepts native text-to-video with no image and integer output duration 4-15s (default 5s); `seedance-mini` supports 480p/720p and is best for cheaper drafts/multi-size tests; MiniMax H3 accepts native text-to-video, 4-15s output, and up to 9 image, up to 3 video, and up to 3 audio references through Makaron Agent/chat. H3 defaults to
|
|
366
|
+
Options for `video create`: `--script "..."`, `--script-file <path>`, `--image <url>` (repeatable, up to the selected model limit), `--video <file|url>` and `--audio <file|url>` (repeatable where supported), `--duration <seconds>`, `--aspect 9:16|16:9|1:1`, `--video-model seedance-fast|seedance-mini|seedance|seedance-2.5|kling|grok|google-omni|minimax-h3`, `--video-resolution auto|480p|720p|768p|1080p|2k|4k`. Default model is `seedance-fast`. SeeDance accepts native text-to-video with no image and integer output duration 4-15s (default 5s); `seedance-mini` supports 480p/720p and is best for cheaper drafts/multi-size tests; MiniMax H3 accepts native text-to-video, 4-15s output, public 768p/2k resolution, and up to 9 image, up to 3 video, and up to 3 audio references through Makaron Agent/chat. H3 defaults to 768p; request 2k explicitly for maximum/final quality. Kling supports 5-15s; Grok 1.5 supports 1-15s single-image-to-video only; Gemini Omni supports 3-10s fast 720p image/video generation and editing with native generated audio, including up to 6 image references when no video reference is provided. For `--video-model grok`, forced `--aspect` is ignored to avoid xAI stretching the source image; pad/create the image at the target shape first or use another model.
|
|
361
367
|
|
|
362
368
|
Seedance 2.5: use `--video-model seedance-2.5` for 4-30 second output at 480p/720p. `--image` accepts local files or URLs (up to 30), while repeatable `--video` and `--audio` accept up to 10 each. Use `--video-operation generate|edit|extend`, `--extend-direction forward|backward`, `--output-format mp4|mov`, `--web-search`, `--generated-audio` / `--no-generated-audio`, and `--relaxed-content-filter`. Edit/extend require a video reference. The Evolink route does not currently expose 4K output.
|
|
363
369
|
|
package/bin/makaron.mjs
CHANGED
|
@@ -28,6 +28,14 @@ const NPM_PACKAGE_NAME = 'makaron-cli';
|
|
|
28
28
|
const UPDATE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
29
29
|
const UPDATE_CHECK_TIMEOUT_MS = 400;
|
|
30
30
|
const AGENT_WAIT_TIMEOUT_SECONDS = Math.max(900, Number(process.env.MAKARON_AGENT_WAIT_TIMEOUT_SECONDS || 10_800));
|
|
31
|
+
const CHAT_AGENT_MODELS = [
|
|
32
|
+
'auto',
|
|
33
|
+
'gpt-5.6-terra',
|
|
34
|
+
'gpt-5.6-sol',
|
|
35
|
+
'gpt-5.6-luna',
|
|
36
|
+
'grok-4.5',
|
|
37
|
+
'deepseek-v4-pro',
|
|
38
|
+
];
|
|
31
39
|
|
|
32
40
|
// Public anon key (safe to embed — only enables auth, not data access)
|
|
33
41
|
const SUPABASE_URL = 'https://sdyrtztrjgmmpnirswxt.supabase.co';
|
|
@@ -59,6 +67,16 @@ function warnLegacyModelFlag(replacement) {
|
|
|
59
67
|
process.stderr.write(`⚠️ --model is deprecated here; use ${replacement}.\n`);
|
|
60
68
|
}
|
|
61
69
|
|
|
70
|
+
function validateChatAgentModel(value) {
|
|
71
|
+
if (!value || !CHAT_AGENT_MODELS.includes(value)) {
|
|
72
|
+
process.stderr.write(`❌ Unknown Agent LLM: ${value || '(missing value)'}\n`);
|
|
73
|
+
process.stderr.write(`Choose one of: ${CHAT_AGENT_MODELS.join(', ')}\n`);
|
|
74
|
+
process.stderr.write('--agent-model selects only the Agent LLM. Put image/video model preferences in the chat prompt, or use the explicit edit/video commands.\n');
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
return value;
|
|
78
|
+
}
|
|
79
|
+
|
|
62
80
|
function getCliVersion() {
|
|
63
81
|
try {
|
|
64
82
|
const pkg = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf-8'));
|
|
@@ -159,51 +177,50 @@ function readJsonInput(filePath) {
|
|
|
159
177
|
const MAX_MEDIA_MANIFEST_RANGES = 20;
|
|
160
178
|
|
|
161
179
|
function normalizeMediaManifest(input) {
|
|
162
|
-
const manifest = Array.isArray(input) ? {
|
|
180
|
+
const manifest = Array.isArray(input) ? { clips: input } : input;
|
|
163
181
|
if (!manifest || typeof manifest !== 'object') {
|
|
164
182
|
throw new Error('Media manifest must be a JSON object or an array of source ranges.');
|
|
165
183
|
}
|
|
166
|
-
const rawRanges = Array.isArray(manifest.
|
|
167
|
-
? manifest.
|
|
168
|
-
: Array.isArray(manifest.
|
|
169
|
-
? manifest.
|
|
170
|
-
:
|
|
184
|
+
const rawRanges = Array.isArray(manifest.clips)
|
|
185
|
+
? manifest.clips
|
|
186
|
+
: Array.isArray(manifest.source_ranges)
|
|
187
|
+
? manifest.source_ranges
|
|
188
|
+
: Array.isArray(manifest.sourceRanges)
|
|
189
|
+
? manifest.sourceRanges
|
|
190
|
+
: null;
|
|
171
191
|
if (!rawRanges?.length) {
|
|
172
|
-
throw new Error('Media manifest must contain a non-empty
|
|
192
|
+
throw new Error('Media manifest must contain a non-empty clips array.');
|
|
173
193
|
}
|
|
174
194
|
if (rawRanges.length > MAX_MEDIA_MANIFEST_RANGES) {
|
|
175
195
|
throw new Error(`Media manifest supports at most ${MAX_MEDIA_MANIFEST_RANGES} source ranges per Makaron task.`);
|
|
176
196
|
}
|
|
177
197
|
|
|
178
198
|
const sourceRanges = rawRanges.map((raw, index) => {
|
|
179
|
-
if (!raw || typeof raw !== 'object') throw new Error(`
|
|
199
|
+
if (!raw || typeof raw !== 'object') throw new Error(`clips[${index}] must be an object.`);
|
|
180
200
|
const sourceUrl = typeof raw.source_url === 'string' ? raw.source_url.trim() : '';
|
|
181
201
|
let parsed;
|
|
182
202
|
try {
|
|
183
203
|
parsed = new URL(sourceUrl);
|
|
184
204
|
} catch {
|
|
185
|
-
throw new Error(`
|
|
205
|
+
throw new Error(`clips[${index}].source_url must be a valid HTTP(S) URL.`);
|
|
186
206
|
}
|
|
187
207
|
if (!['http:', 'https:'].includes(parsed.protocol)) {
|
|
188
|
-
throw new Error(`
|
|
208
|
+
throw new Error(`clips[${index}].source_url must use HTTP or HTTPS.`);
|
|
189
209
|
}
|
|
190
|
-
const
|
|
191
|
-
const
|
|
192
|
-
if (!Number.isFinite(
|
|
193
|
-
throw new Error(`
|
|
210
|
+
const start = Number(raw.start ?? raw.start_sec);
|
|
211
|
+
const end = Number(raw.end ?? raw.end_sec);
|
|
212
|
+
if (!Number.isFinite(start) || start < 0) {
|
|
213
|
+
throw new Error(`clips[${index}].start must be a finite number >= 0.`);
|
|
194
214
|
}
|
|
195
|
-
if (!Number.isFinite(
|
|
196
|
-
throw new Error(`
|
|
215
|
+
if (!Number.isFinite(end) || end <= start) {
|
|
216
|
+
throw new Error(`clips[${index}].end must be greater than start.`);
|
|
197
217
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (Number.isFinite(value) && value > 0) range[key] = value;
|
|
205
|
-
}
|
|
206
|
-
return range;
|
|
218
|
+
return {
|
|
219
|
+
source_url: sourceUrl,
|
|
220
|
+
start,
|
|
221
|
+
end,
|
|
222
|
+
description: typeof raw.description === 'string' ? raw.description.trim() : '',
|
|
223
|
+
};
|
|
207
224
|
});
|
|
208
225
|
|
|
209
226
|
return {
|
|
@@ -350,15 +367,17 @@ Options:
|
|
|
350
367
|
--image <file|url> Attach a reference image or screenshot. Repeatable.
|
|
351
368
|
--video <file|url> Attach a video to the project timeline. Repeatable.
|
|
352
369
|
--audio <file|url> Attach a song, beat, or voice reference. MP3/WAV, repeatable.
|
|
353
|
-
--media-manifest <file|-> Import source_url +
|
|
370
|
+
--media-manifest <file|-> Import source_url + start + end + description clips before this run.
|
|
354
371
|
--skill <id|label|name> Use an installed skill or auto-install a matched marketplace skill.
|
|
372
|
+
--agent-model <id> Agent LLM only: auto, gpt-5.6-terra, gpt-5.6-sol,
|
|
373
|
+
gpt-5.6-luna, grok-4.5, or deepseek-v4-pro.
|
|
355
374
|
--background, -b Submit and print a runId.
|
|
356
375
|
--json Output structured JSON.
|
|
357
376
|
--stream Legacy live SSE stream.
|
|
358
377
|
--help, -h Show this help.
|
|
359
378
|
|
|
360
|
-
|
|
361
|
-
--video-model,
|
|
379
|
+
Agent LLM defaults to auto (currently gpt-5.6-terra). Image/video model routing
|
|
380
|
+
stays automatic in chat; --image-model, --video-model, and --model are rejected.
|
|
362
381
|
|
|
363
382
|
What you can ask:
|
|
364
383
|
Image edit
|
|
@@ -382,6 +401,9 @@ What you can ask:
|
|
|
382
401
|
Agent-to-agent source-range handoff
|
|
383
402
|
makaron chat --project auto --media-manifest set-01.json -b --json "make a 30s vertical video"
|
|
384
403
|
|
|
404
|
+
Compare Agent LLMs with identical inputs
|
|
405
|
+
makaron chat --project auto --agent-model deepseek-v4-pro -b --json "make a 20s badminton video"
|
|
406
|
+
|
|
385
407
|
Music
|
|
386
408
|
makaron chat --project <id> "add calm piano background music"
|
|
387
409
|
|
|
@@ -423,6 +445,7 @@ async function streamAgent(baseUrl, headers, projectId, prompt, opts = {}) {
|
|
|
423
445
|
projectId,
|
|
424
446
|
prompt,
|
|
425
447
|
headless: true,
|
|
448
|
+
...(opts.agentModel ? { agentModel: opts.agentModel } : {}),
|
|
426
449
|
...(opts.uploadedVideoCount ? { uploadedVideoCount: opts.uploadedVideoCount } : {}),
|
|
427
450
|
...(opts.turnMediaCount ? { turnMediaCount: opts.turnMediaCount } : {}),
|
|
428
451
|
}),
|
|
@@ -531,6 +554,7 @@ async function streamAgent(baseUrl, headers, projectId, prompt, opts = {}) {
|
|
|
531
554
|
|
|
532
555
|
async function submitRun(baseUrl, headers, projectId, prompt, opts = {}) {
|
|
533
556
|
const body = { projectId, prompt };
|
|
557
|
+
if (opts.agentModel) body.agentModel = opts.agentModel;
|
|
534
558
|
if (opts.currentSnapshotIndex != null) body.currentSnapshotIndex = opts.currentSnapshotIndex;
|
|
535
559
|
if (opts.isNsfw) body.isNsfw = opts.isNsfw;
|
|
536
560
|
if (opts.audioAttachments?.length) body.audioAttachments = opts.audioAttachments;
|
|
@@ -910,7 +934,7 @@ async function addProjectMediaSourceRanges(baseUrl, headers, projectId, ranges,
|
|
|
910
934
|
const res = await fetch(`${baseUrl}/api/projects/${projectId}/media`, {
|
|
911
935
|
method: 'POST',
|
|
912
936
|
headers: { 'Content-Type': 'application/json', ...headers },
|
|
913
|
-
body: JSON.stringify({
|
|
937
|
+
body: JSON.stringify({ clips: ranges }),
|
|
914
938
|
});
|
|
915
939
|
if (!res.ok) { console.error('Project media add failed:', await res.text()); process.exit(1); }
|
|
916
940
|
const data = await res.json();
|
|
@@ -1686,7 +1710,7 @@ Commands:
|
|
|
1686
1710
|
credits Show current credit balance
|
|
1687
1711
|
list (ls) List all projects
|
|
1688
1712
|
project media <projectId> --json List timeline media for a project
|
|
1689
|
-
project media add <projectId> --source-url <url> --start
|
|
1713
|
+
project media add <projectId> --source-url <url> --start <n> --end <n>
|
|
1690
1714
|
Add an external source range without uploading video
|
|
1691
1715
|
create --image <file> Create project from local image
|
|
1692
1716
|
create --image-url <url> Create project from URL
|
|
@@ -1694,6 +1718,8 @@ Commands:
|
|
|
1694
1718
|
|
|
1695
1719
|
chat --project <id> "message" Chat (non-blocking, polls for result)
|
|
1696
1720
|
chat --project <id> --skill <id> Use a built-in or marketplace skill
|
|
1721
|
+
chat --project <id> --agent-model <id> "message"
|
|
1722
|
+
Select only the Agent LLM (strict allowlist)
|
|
1697
1723
|
chat --project <id> --video <file> Attach video to conversation
|
|
1698
1724
|
chat --project <id> --audio <file> Attach song/beat/voice reference
|
|
1699
1725
|
chat --project auto --media-manifest <file> "message"
|
|
@@ -1727,7 +1753,8 @@ Examples:
|
|
|
1727
1753
|
makaron chat --project <id> "turn this into a short video"
|
|
1728
1754
|
|
|
1729
1755
|
Run makaron <command> --help for command-specific options.
|
|
1730
|
-
Chat
|
|
1756
|
+
Chat defaults the Agent LLM automatically; --agent-model can select an exact
|
|
1757
|
+
Agent LLM. Image and video model routing remains automatic in chat.
|
|
1731
1758
|
|
|
1732
1759
|
Environment:
|
|
1733
1760
|
MAKARON_API_KEY API key (mk_live_xxx) — recommended for agents
|
|
@@ -1806,11 +1833,11 @@ function printHelp(topic, subtopic) {
|
|
|
1806
1833
|
console.log('Usage: makaron credits [--json]');
|
|
1807
1834
|
} else if (topic === 'project' || topic === 'projects') {
|
|
1808
1835
|
if (subtopic === 'media') console.log(`Usage: makaron project media <projectId> [--json]
|
|
1809
|
-
makaron project media add <projectId> --source-url <url> --start
|
|
1836
|
+
makaron project media add <projectId> --source-url <url> --start <n> --end <n> [--description <text>] [--json]
|
|
1810
1837
|
makaron project media add <projectId> --input <ranges.json> [--json]`);
|
|
1811
1838
|
else console.log(`Project commands:
|
|
1812
1839
|
project media <projectId> --json List timeline media for a project
|
|
1813
|
-
project media add <projectId> ... Add external source_url +
|
|
1840
|
+
project media add <projectId> ... Add external source_url + start + end media
|
|
1814
1841
|
`);
|
|
1815
1842
|
} else if (topic === 'abort') {
|
|
1816
1843
|
console.log('Usage: makaron abort <runId>');
|
|
@@ -1855,7 +1882,7 @@ Use with chat:
|
|
|
1855
1882
|
else console.log(`Video commands:
|
|
1856
1883
|
video script --image <file> [--image <file>] "direction" Write video script
|
|
1857
1884
|
video create --script "..." --video-model seedance-fast Native text-to-video (no image required)
|
|
1858
|
-
video create --script "..." --video-model minimax-h3
|
|
1885
|
+
video create --script "..." --video-model minimax-h3 MiniMax H3 text-to-video (default 768P)
|
|
1859
1886
|
video create --script "..." --image <url> [--duration 10] Submit video task
|
|
1860
1887
|
video create --script "..." --video <public-url> [--video-model seedance-fast|seedance-mini|seedance|seedance-2.5|kling|google-omni|minimax-h3] Edit/reference a video (Grok does not support video refs)
|
|
1861
1888
|
video status <taskId> Check video status
|
|
@@ -1969,6 +1996,7 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
1969
1996
|
let jsonOutput = false;
|
|
1970
1997
|
let activeSkill = undefined;
|
|
1971
1998
|
let mediaManifestPath = undefined;
|
|
1999
|
+
let agentModel = undefined;
|
|
1972
2000
|
for (let i = 1; i < args.length; i++) {
|
|
1973
2001
|
if (args[i] === '--project' && args[i + 1]) projectId = args[++i];
|
|
1974
2002
|
else if (args[i] === '--image' && args[i + 1]) chatImages.push(args[++i]);
|
|
@@ -1984,6 +2012,21 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
1984
2012
|
else if (args[i].startsWith('--media-manifest=')) mediaManifestPath = args[i].slice('--media-manifest='.length);
|
|
1985
2013
|
else if (args[i] === '--skill' && args[i + 1]) activeSkill = args[++i];
|
|
1986
2014
|
else if (args[i].startsWith('--skill=')) activeSkill = args[i].slice('--skill='.length);
|
|
2015
|
+
else if (args[i] === '--agent-model') {
|
|
2016
|
+
if (agentModel !== undefined) {
|
|
2017
|
+
process.stderr.write('❌ Pass --agent-model only once per chat run.\n');
|
|
2018
|
+
process.exit(1);
|
|
2019
|
+
}
|
|
2020
|
+
if (!args[i + 1] || args[i + 1].startsWith('--')) validateChatAgentModel('');
|
|
2021
|
+
agentModel = validateChatAgentModel(args[++i]);
|
|
2022
|
+
}
|
|
2023
|
+
else if (args[i].startsWith('--agent-model=')) {
|
|
2024
|
+
if (agentModel !== undefined) {
|
|
2025
|
+
process.stderr.write('❌ Pass --agent-model only once per chat run.\n');
|
|
2026
|
+
process.exit(1);
|
|
2027
|
+
}
|
|
2028
|
+
agentModel = validateChatAgentModel(args[i].slice('--agent-model='.length));
|
|
2029
|
+
}
|
|
1987
2030
|
else if (args[i] === '--stream') useStream = true;
|
|
1988
2031
|
else if (args[i] === '--background' || args[i] === '-b') background = true;
|
|
1989
2032
|
else if (args[i] === '--json') jsonOutput = true;
|
|
@@ -1992,11 +2035,11 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
1992
2035
|
process.exit(1);
|
|
1993
2036
|
}
|
|
1994
2037
|
else if (
|
|
1995
|
-
['--
|
|
1996
|
-
|| ['--
|
|
2038
|
+
['--image-model', '--video-model', '--model'].includes(args[i])
|
|
2039
|
+
|| ['--image-model=', '--video-model=', '--model='].some(prefix => args[i].startsWith(prefix))
|
|
1997
2040
|
) {
|
|
1998
2041
|
const flag = args[i].split('=')[0];
|
|
1999
|
-
process.stderr.write(`❌ makaron chat
|
|
2042
|
+
process.stderr.write(`❌ ${flag} is not valid for makaron chat. Only --agent-model may select the Agent LLM; image/video routing stays automatic. Remove ${flag} and retry.\n`);
|
|
2000
2043
|
process.exit(1);
|
|
2001
2044
|
}
|
|
2002
2045
|
else promptParts.push(args[i]);
|
|
@@ -2223,6 +2266,7 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
2223
2266
|
if (useStream) {
|
|
2224
2267
|
// Legacy SSE mode
|
|
2225
2268
|
const { results } = await streamAgent(baseUrl, headers, projectId, finalPrompt, {
|
|
2269
|
+
agentModel,
|
|
2226
2270
|
uploadedVideoCount: uploadedTurnVideoCount,
|
|
2227
2271
|
turnMediaCount: uploadedTurnMediaCount,
|
|
2228
2272
|
});
|
|
@@ -2235,6 +2279,7 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
2235
2279
|
} else {
|
|
2236
2280
|
// Default: fire-and-forget + poll
|
|
2237
2281
|
const { runId } = await submitRun(baseUrl, headers, projectId, finalPrompt, {
|
|
2282
|
+
agentModel,
|
|
2238
2283
|
audioAttachments,
|
|
2239
2284
|
uploadedVideoCount: uploadedTurnVideoCount,
|
|
2240
2285
|
turnMediaCount: uploadedTurnMediaCount,
|
|
@@ -2496,7 +2541,7 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
2496
2541
|
const jsonOutput = args.includes('--json');
|
|
2497
2542
|
if (args[2] === 'add') {
|
|
2498
2543
|
const projectId = args[3];
|
|
2499
|
-
if (!projectId) { console.error('Usage: makaron project media add <projectId> --source-url <url> --start
|
|
2544
|
+
if (!projectId) { console.error('Usage: makaron project media add <projectId> --source-url <url> --start <n> --end <n>'); process.exit(1); }
|
|
2500
2545
|
const readOption = (name) => {
|
|
2501
2546
|
const index = args.indexOf(name);
|
|
2502
2547
|
return index >= 0 ? args[index + 1] : undefined;
|
|
@@ -2505,28 +2550,24 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
2505
2550
|
let ranges;
|
|
2506
2551
|
if (inputPath) {
|
|
2507
2552
|
const input = readJsonInput(inputPath);
|
|
2508
|
-
ranges = Array.isArray(input) ? input : input.source_ranges || input.sourceRanges;
|
|
2553
|
+
ranges = Array.isArray(input) ? input : input.clips || input.source_ranges || input.sourceRanges;
|
|
2509
2554
|
} else {
|
|
2510
2555
|
const sourceUrl = readOption('--source-url');
|
|
2511
|
-
const
|
|
2512
|
-
const
|
|
2513
|
-
if (!sourceUrl || !Number.isFinite(
|
|
2514
|
-
console.error('Provide --source-url, --start
|
|
2556
|
+
const start = Number(readOption('--start') ?? readOption('--start-sec'));
|
|
2557
|
+
const end = Number(readOption('--end') ?? readOption('--end-sec'));
|
|
2558
|
+
if (!sourceUrl || !Number.isFinite(start) || !Number.isFinite(end)) {
|
|
2559
|
+
console.error('Provide --source-url, --start, and --end, or --input <manifest.json>.');
|
|
2515
2560
|
process.exit(1);
|
|
2516
2561
|
}
|
|
2517
2562
|
ranges = [{
|
|
2518
2563
|
source_url: sourceUrl,
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
...(readOption('--source-uri') ? { source_uri: readOption('--source-uri') } : {}),
|
|
2522
|
-
...(readOption('--project-id') ? { project_id: readOption('--project-id') } : {}),
|
|
2523
|
-
...(readOption('--asset-id') ? { asset_id: readOption('--asset-id') } : {}),
|
|
2524
|
-
...(readOption('--file-name') ? { file_name: readOption('--file-name') } : {}),
|
|
2564
|
+
start,
|
|
2565
|
+
end,
|
|
2525
2566
|
...(readOption('--description') ? { description: readOption('--description') } : {}),
|
|
2526
2567
|
}];
|
|
2527
2568
|
}
|
|
2528
2569
|
if (!Array.isArray(ranges) || !ranges.length) {
|
|
2529
|
-
console.error('Input must contain a non-empty
|
|
2570
|
+
console.error('Input must contain a non-empty clips array.');
|
|
2530
2571
|
process.exit(1);
|
|
2531
2572
|
}
|
|
2532
2573
|
await addProjectMediaSourceRanges(baseUrl, headers, projectId, ranges, { json: jsonOutput });
|
|
@@ -2538,7 +2579,7 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
2538
2579
|
} else {
|
|
2539
2580
|
console.log(`Project commands:
|
|
2540
2581
|
project media <projectId> --json List timeline media for a project
|
|
2541
|
-
project media add <projectId> ... Add external source_url +
|
|
2582
|
+
project media add <projectId> ... Add external source_url + start + end media
|
|
2542
2583
|
`);
|
|
2543
2584
|
}
|
|
2544
2585
|
} else if (command === 'abort') {
|
|
@@ -2781,7 +2822,7 @@ if (!command || command === '--help' || command === '-h' || command === 'help')
|
|
|
2781
2822
|
console.log(`Video commands:
|
|
2782
2823
|
video script --image <file> [--image <file>] "direction" Write video script
|
|
2783
2824
|
video create --script "..." --video-model seedance-fast Native text-to-video (no image required)
|
|
2784
|
-
video create --script "..." --video-model minimax-h3
|
|
2825
|
+
video create --script "..." --video-model minimax-h3 MiniMax H3 text-to-video (default 768P)
|
|
2785
2826
|
video create --script "..." --image <url> [--duration 10] Submit video task
|
|
2786
2827
|
video create --script "..." --video <public-url> [--video-model seedance-fast|seedance-mini|seedance|seedance-2.5|kling|google-omni|minimax-h3] Edit/reference a video (Grok does not support video refs)
|
|
2787
2828
|
video status <taskId> Check video status
|
package/package.json
CHANGED
package/skills/makaron/SKILL.md
CHANGED
|
@@ -85,7 +85,11 @@ npx makaron-cli chat --project auto --image photo.jpg --json -b "make it cinemat
|
|
|
85
85
|
npx makaron-cli chat --project auto --image img1.jpg --image img2.jpg --json -b "combine these"
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
`chat`
|
|
88
|
+
`chat` routes image and video models automatically. Use `--agent-model` only when the user explicitly asks to select or compare the reasoning/tool-calling Agent LLM. Accepted values are exactly `auto`, `gpt-5.6-terra`, `gpt-5.6-sol`, `gpt-5.6-luna`, `grok-4.5`, and `deepseek-v4-pro`; `auto` currently resolves to `gpt-5.6-terra`. Never put an image or video model ID in `--agent-model`. The CLI rejects unknown Agent IDs plus `--image-model`, `--video-model`, and legacy `--model` before starting a chat run.
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npx makaron-cli chat --project auto --agent-model deepseek-v4-pro --json -b "make a 20s badminton video"
|
|
92
|
+
```
|
|
89
93
|
|
|
90
94
|
Returns immediately:
|
|
91
95
|
```json
|
|
@@ -152,11 +156,11 @@ This is project-scoped. `responses get <runId> --pick output` only returns artif
|
|
|
152
156
|
Publish an external video interval directly into that Media List without uploading the original or a derivative MP4:
|
|
153
157
|
|
|
154
158
|
```bash
|
|
155
|
-
npx makaron-cli project media add <projectId> --source-url "https://cdn.example.com/source.mp4" --start
|
|
159
|
+
npx makaron-cli project media add <projectId> --source-url "https://cdn.example.com/source.mp4" --start 12.5 --end 19 --description "Racket frame molding"
|
|
156
160
|
npx makaron-cli project media add <projectId> --input ranges.json --json
|
|
157
161
|
```
|
|
158
162
|
|
|
159
|
-
The JSON input may be an array or `{ "
|
|
163
|
+
The JSON input may be an array or `{ "clips": [...] }`. Each clip has exactly `source_url + start + end + description`; `start` and `end` are seconds, array order is edit order, and `source_url` is opaque. Do not add or request provider-specific identity fields. Put existing media understanding (summary, editorial purpose, scene evidence, confidence, and limitations) in `description`. Makaron reads that provider-neutral Media List field before deciding whether any additional image/video analysis is needed.
|
|
160
164
|
|
|
161
165
|
For one-call orchestration, use `chat --project auto --media-manifest plan.json`. Makaron validates the manifest, creates the project, imports its ranges, and starts the Agent. If an upstream service returns multiple plans, the caller should start one independent Makaron task per plan instead of passing the provider-specific batch response into Makaron.
|
|
162
166
|
|
|
@@ -280,7 +284,7 @@ npx makaron-cli video create --script "Shot 1 (15s): <<<image_1>>> and <<<image_
|
|
|
280
284
|
|
|
281
285
|
# 3b. Native SeeDance or MiniMax H3 text-to-video (no image required)
|
|
282
286
|
npx makaron-cli video create --script "Shot 1 (5s): A neon one-person studio wakes at dawn" --duration 5 --video-model seedance-fast --aspect 16:9
|
|
283
|
-
npx makaron-cli video create --script "Shot 1 (15s): A premium creative editor comes alive" --duration 15 --video-model minimax-h3 --
|
|
287
|
+
npx makaron-cli video create --script "Shot 1 (15s): A premium creative editor comes alive" --duration 15 --video-model minimax-h3 --aspect 16:9
|
|
284
288
|
|
|
285
289
|
# 3c. Edit a video from a local file or public URL
|
|
286
290
|
npx makaron-cli video create --script "make it funny" --video input.mp4 --duration 5 --video-model seedance-fast
|
|
@@ -296,7 +300,7 @@ npx makaron-cli video status <taskId>
|
|
|
296
300
|
npx makaron-cli chat --project <id|auto> --video input.mp4 -b "make it funny"
|
|
297
301
|
```
|
|
298
302
|
|
|
299
|
-
Options for `video create`: `--script "..."`, `--script-file <path>`, `--image <url>` (repeatable, up to the selected model limit), `--video <file|url>` and `--audio <file|url>` (repeatable where supported), `--duration <seconds>`, `--aspect 9:16|16:9|1:1`, `--video-model seedance-fast|seedance-mini|seedance|seedance-2.5|kling|grok|google-omni|minimax-h3`, `--video-resolution auto|480p|720p|768p|1080p|2k|4k`. Default model is `seedance-fast`. SeeDance accepts native text-to-video with no image and integer output duration 4-15s (default 5s); `seedance-mini` supports 480p/720p and is best for cheaper drafts/multi-size tests; MiniMax H3 accepts native text-to-video, 4-15s output, and up to 9 image, up to 3 video, and up to 3 audio references through Makaron Agent/chat. H3 defaults to
|
|
303
|
+
Options for `video create`: `--script "..."`, `--script-file <path>`, `--image <url>` (repeatable, up to the selected model limit), `--video <file|url>` and `--audio <file|url>` (repeatable where supported), `--duration <seconds>`, `--aspect 9:16|16:9|1:1`, `--video-model seedance-fast|seedance-mini|seedance|seedance-2.5|kling|grok|google-omni|minimax-h3`, `--video-resolution auto|480p|720p|768p|1080p|2k|4k`. Default model is `seedance-fast`. SeeDance accepts native text-to-video with no image and integer output duration 4-15s (default 5s); `seedance-mini` supports 480p/720p and is best for cheaper drafts/multi-size tests; MiniMax H3 accepts native text-to-video, 4-15s output, public 768p/2k resolution, and up to 9 image, up to 3 video, and up to 3 audio references through Makaron Agent/chat. H3 defaults to 768p; request 2k explicitly for maximum/final quality. Kling supports 5-15s; Grok 1.5 supports 1-15s single-image-to-video only; Gemini Omni supports 3-10s fast 720p image/video generation and editing with native generated audio, including up to 6 image references when no video reference is provided. For `--video-model grok`, forced `--aspect` is ignored to avoid xAI stretching the source image; pad/create the image at the target shape first or use another model.
|
|
300
304
|
|
|
301
305
|
Seedance 2.5 uses `--video-model seedance-2.5` and supports 4-30s at 480p/720p, up to 30 images + 10 videos + 10 audios, repeatable local/URL references, `--video-operation generate|edit|extend`, `--extend-direction`, `--output-format mp4|mov`, and `--web-search`. The Evolink route does not currently expose 4K output.
|
|
302
306
|
|