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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "makaron-cli",
3
- "version": "0.13.5",
3
+ "version": "0.13.7",
4
4
  "description": "Give Claude Code a creative agent. Pass complete creative requests and source media to Makaron Chat.",
5
5
  "author": {
6
6
  "name": "Versa AI",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "makaron-cli",
3
- "version": "0.13.5",
3
+ "version": "0.13.7",
4
4
  "description": "Give Codex a creative agent. Pass complete creative requests and source media to Makaron Chat.",
5
5
  "author": {
6
6
  "name": "Versa AI",
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` always routes agent, image, and video models automatically. Never pass `--agent-model`, `--image-model`, `--video-model`, or the legacy `--model` flag to `chat`; the CLI rejects them before starting a run. Model flags remain available only on explicit low-level commands such as `edit` and `video create`.
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-sec 12.5 --end-sec 19 \
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 {"source_ranges": [...]}
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": "...", "source_ranges": [...] }`.
185
- It is validated before project creation and supports up to 20 ranges for one
186
- Makaron task. Batch planning remains the upstream orchestrator's responsibility:
187
- convert each plan into one manifest and start one independent Makaron task.
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 --video-resolution 2k --aspect 16:9
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 public 2k output; 768p requires provider preview access plus `MINIMAX_H3_ENABLE_768P=true` on the Makaron server. 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.
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) ? { source_ranges: input } : 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.source_ranges)
167
- ? manifest.source_ranges
168
- : Array.isArray(manifest.sourceRanges)
169
- ? manifest.sourceRanges
170
- : null;
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 source_ranges array.');
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(`source_ranges[${index}] must be an object.`);
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(`source_ranges[${index}].source_url must be a valid HTTP(S) URL.`);
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(`source_ranges[${index}].source_url must use HTTP or HTTPS.`);
208
+ throw new Error(`clips[${index}].source_url must use HTTP or HTTPS.`);
189
209
  }
190
- const startSec = Number(raw.start_sec);
191
- const endSec = Number(raw.end_sec);
192
- if (!Number.isFinite(startSec) || startSec < 0) {
193
- throw new Error(`source_ranges[${index}].start_sec must be a finite number >= 0.`);
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(endSec) || endSec <= startSec) {
196
- throw new Error(`source_ranges[${index}].end_sec must be greater than start_sec.`);
215
+ if (!Number.isFinite(end) || end <= start) {
216
+ throw new Error(`clips[${index}].end must be greater than start.`);
197
217
  }
198
- const range = { source_url: sourceUrl, start_sec: startSec, end_sec: endSec };
199
- for (const key of ['source_uri', 'project_id', 'asset_id', 'file_name', 'description']) {
200
- if (typeof raw[key] === 'string' && raw[key].trim()) range[key] = raw[key].trim();
201
- }
202
- for (const key of ['width', 'height']) {
203
- const value = Number(raw[key]);
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 + start_sec + end_sec ranges before this run.
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
- Model routing is automatic in chat. Do not pass --agent-model, --image-model,
361
- --video-model, or the legacy --model flag.
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({ source_ranges: ranges }),
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-sec <n> --end-sec <n>
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 chooses agent, image, and video models automatically.
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-sec <n> --end-sec <n> [--source-uri <uri>] [--description <text>] [--json]
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 + start_sec + end_sec media
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 --video-resolution 2k MiniMax H3 native 2K text-to-video
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
- ['--agent-model', '--image-model', '--video-model', '--model'].includes(args[i])
1996
- || ['--agent-model=', '--image-model=', '--video-model=', '--model='].some(prefix => args[i].startsWith(prefix))
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 chooses agent, image, and video models automatically. Remove ${flag} and retry.\n`);
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-sec <n> --end-sec <n>'); process.exit(1); }
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 startSec = Number(readOption('--start-sec'));
2512
- const endSec = Number(readOption('--end-sec'));
2513
- if (!sourceUrl || !Number.isFinite(startSec) || !Number.isFinite(endSec)) {
2514
- console.error('Provide --source-url, --start-sec, and --end-sec, or --input <ranges.json>.');
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
- start_sec: startSec,
2520
- end_sec: endSec,
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 source_ranges array.');
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 + start_sec + end_sec media
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 --video-resolution 2k MiniMax H3 native 2K text-to-video
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "makaron-cli",
3
- "version": "0.13.5",
3
+ "version": "0.13.7",
4
4
  "description": "Talk to Makaron Agent from the terminal — create projects, edit images, generate videos",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -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` always routes agent, image, and video models automatically. Never pass `--agent-model`, `--image-model`, `--video-model`, or the legacy `--model` flag to `chat`; the CLI rejects them before starting a run. Model flags remain available only on explicit low-level commands such as `edit` and `video create`.
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-sec 12.5 --end-sec 19 --source-uri "dam://project/asset" --description "Racket frame molding"
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 `{ "source_ranges": [...] }`. Each item uses `source_url + start_sec + end_sec`; optional `source_uri`, `project_id`, and `asset_id` preserve durable source identity. 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.
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 --video-resolution 2k --aspect 16:9
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 public 2k output; 768p requires provider preview access plus `MINIMAX_H3_ENABLE_768P=true` on the Makaron server. 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.
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