@melius-ai/cli 0.14.0 → 0.15.0

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/dist/bin/mel.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  printUpgradeNoticeIfNeeded,
8
8
  withDefaultHelp,
9
9
  writeError
10
- } from "../chunk-RTPRU2JD.js";
10
+ } from "../chunk-VOIPEX54.js";
11
11
 
12
12
  // bin/mel.ts
13
13
  var program = createProgram();
@@ -9343,6 +9343,84 @@ var ListAudioVoicesResponseSchema = external_exports.object({
9343
9343
  hasMore: external_exports.boolean(),
9344
9344
  totalCount: external_exports.number()
9345
9345
  });
9346
+ var FISH_AUDIO_VOICE_LIBRARY_STYLES = [
9347
+ { value: "narration", label: "Narration" },
9348
+ { value: "conversational", label: "Conversational" },
9349
+ { value: "character-voice", label: "Characters" },
9350
+ { value: "social-media", label: "Social media" },
9351
+ { value: "educational", label: "Educational" },
9352
+ { value: "advertisement", label: "Advertisement" },
9353
+ { value: "entertainment", label: "Entertainment" },
9354
+ { value: "storytelling", label: "Storytelling" },
9355
+ { value: "announcer", label: "Announcer" },
9356
+ { value: "cinematic", label: "Cinematic" }
9357
+ ];
9358
+ var FISH_AUDIO_VOICE_LIBRARY_TONES = [
9359
+ { value: "calm", label: "Calm" },
9360
+ { value: "energetic", label: "Energetic" },
9361
+ { value: "deep", label: "Deep" },
9362
+ { value: "soft", label: "Soft" },
9363
+ { value: "clear", label: "Clear" },
9364
+ { value: "confident", label: "Confident" },
9365
+ { value: "authoritative", label: "Authoritative" },
9366
+ { value: "dramatic", label: "Dramatic" },
9367
+ { value: "expressive", label: "Expressive" },
9368
+ { value: "friendly", label: "Friendly" },
9369
+ { value: "professional", label: "Professional" }
9370
+ ];
9371
+ var FISH_AUDIO_VOICE_LIBRARY_FILTER_OPTIONS = {
9372
+ gender: ["male", "female", "neutral"],
9373
+ age: ["young", "middle-aged", "old"],
9374
+ style: FISH_AUDIO_VOICE_LIBRARY_STYLES.map((entry) => entry.value),
9375
+ tone: FISH_AUDIO_VOICE_LIBRARY_TONES.map((entry) => entry.value),
9376
+ language: [
9377
+ "en",
9378
+ "es",
9379
+ "zh",
9380
+ "ar",
9381
+ "pt",
9382
+ "ru",
9383
+ "ja",
9384
+ "fr",
9385
+ "de",
9386
+ "ko",
9387
+ "it",
9388
+ "hi",
9389
+ "el",
9390
+ "ro",
9391
+ "sv",
9392
+ "tl"
9393
+ ]
9394
+ };
9395
+ var FishAudioVoiceResponseSchema = external_exports.object({
9396
+ voiceId: external_exports.string(),
9397
+ name: external_exports.string(),
9398
+ description: external_exports.string(),
9399
+ previewUrl: external_exports.string().url().nullable(),
9400
+ tags: external_exports.array(external_exports.string()),
9401
+ languages: external_exports.array(external_exports.string()),
9402
+ /**
9403
+ * Titles are not unique in Fish's user-uploaded catalog, so popularity is
9404
+ * what tells two same-named clones apart. Optional so an older core can
9405
+ * still satisfy a newer client mid-rollout.
9406
+ */
9407
+ likeCount: external_exports.number().optional()
9408
+ });
9409
+ var ListFishAudioVoicesQuerySchema = external_exports.object({
9410
+ page: external_exports.coerce.number().int().min(0).default(0),
9411
+ /** Matched by Fish as a case-insensitive substring of the voice title. */
9412
+ search: external_exports.string().optional(),
9413
+ gender: external_exports.enum(asZodEnum(FISH_AUDIO_VOICE_LIBRARY_FILTER_OPTIONS.gender)).optional(),
9414
+ age: external_exports.enum(asZodEnum(FISH_AUDIO_VOICE_LIBRARY_FILTER_OPTIONS.age)).optional(),
9415
+ style: external_exports.enum(asZodEnum(FISH_AUDIO_VOICE_LIBRARY_FILTER_OPTIONS.style)).optional(),
9416
+ tone: external_exports.enum(asZodEnum(FISH_AUDIO_VOICE_LIBRARY_FILTER_OPTIONS.tone)).optional(),
9417
+ language: external_exports.enum(asZodEnum(FISH_AUDIO_VOICE_LIBRARY_FILTER_OPTIONS.language)).optional()
9418
+ });
9419
+ var ListFishAudioVoicesResponseSchema = external_exports.object({
9420
+ voices: external_exports.array(FishAudioVoiceResponseSchema),
9421
+ page: external_exports.number(),
9422
+ hasMore: external_exports.boolean()
9423
+ });
9346
9424
  var AudioForbiddenResponseSchema = external_exports.object({
9347
9425
  message: external_exports.string()
9348
9426
  });
@@ -9369,6 +9447,29 @@ var ListFavoriteVoicesResponseSchema = external_exports.object({
9369
9447
  voices: external_exports.array(AudioVoiceResponseSchema)
9370
9448
  });
9371
9449
  var audioContract = c5.router({
9450
+ listFishAudioVoices: {
9451
+ method: "GET",
9452
+ path: "/audio/fish-audio/voices",
9453
+ query: ListFishAudioVoicesQuerySchema,
9454
+ responses: {
9455
+ 200: ListFishAudioVoicesResponseSchema,
9456
+ 403: AudioForbiddenResponseSchema
9457
+ }
9458
+ },
9459
+ // A picked voice can be off every page the picker has loaded, so the
9460
+ // trigger resolves its name by id rather than scanning the catalog.
9461
+ getFishAudioVoice: {
9462
+ method: "GET",
9463
+ path: "/audio/fish-audio/voices/:voiceId",
9464
+ pathParams: external_exports.object({
9465
+ voiceId: external_exports.string().trim().min(1)
9466
+ }),
9467
+ responses: {
9468
+ 200: FishAudioVoiceResponseSchema,
9469
+ 403: AudioForbiddenResponseSchema,
9470
+ 404: AudioVoiceNotFoundResponseSchema
9471
+ }
9472
+ },
9372
9473
  listVoices: {
9373
9474
  method: "GET",
9374
9475
  path: "/audio/voices",
@@ -10120,6 +10221,7 @@ var ELEVENLABS_OUTPUT_FORMATS = [
10120
10221
  var ElevenLabsOutputFormatSchema = external_exports.enum(
10121
10222
  ELEVENLABS_OUTPUT_FORMATS.map((f) => f.value)
10122
10223
  );
10224
+ var ELEVENLABS_V3_MODEL_ID = "eleven_v3";
10123
10225
  var slider01 = (defaultValue) => ({
10124
10226
  min: 0,
10125
10227
  max: 1,
@@ -10583,6 +10685,14 @@ var CanvasResponseSchema = external_exports.object({
10583
10685
  createdAt: external_exports.string().datetime(),
10584
10686
  updatedAt: external_exports.string().datetime()
10585
10687
  });
10688
+ var CanvasVersionFavoriteSchema = external_exports.object({
10689
+ nodeId: external_exports.string().uuid(),
10690
+ versionId: external_exports.string().uuid(),
10691
+ favoritedByUserId: external_exports.string().uuid()
10692
+ });
10693
+ var CanvasVersionFavoritesResponseSchema = external_exports.object({
10694
+ favorites: external_exports.array(CanvasVersionFavoriteSchema)
10695
+ });
10586
10696
  var GeometrySchema = external_exports.object({
10587
10697
  x: external_exports.number(),
10588
10698
  y: external_exports.number(),
@@ -10624,10 +10734,12 @@ var ModelConfigSchema = external_exports.object({
10624
10734
  // ratios + resolution that produced it.
10625
10735
  ratios: external_exports.array(external_exports.string()).optional(),
10626
10736
  resolution: external_exports.string().optional(),
10627
- /** Audio-only: stock ElevenLabs voice id used for this version's generation. */
10737
+ /** Audio-only: voice used for generation. */
10628
10738
  voiceId: external_exports.string().optional(),
10629
10739
  /** Audio-only: team custom voice id; takes precedence over voiceId on version switch. */
10630
10740
  customVoiceId: external_exports.string().uuid().optional(),
10741
+ /** Audio-only: the run intentionally used the provider's default voice. */
10742
+ usesProviderDefaultVoice: external_exports.literal(true).optional(),
10631
10743
  /** better-font-32b only: the font the model renders the requested text in (supplied to the model as a rendered reference image). */
10632
10744
  font: external_exports.object({
10633
10745
  source: external_exports.enum(["custom", "google"]),
@@ -10665,6 +10777,8 @@ var OutputResolutionPresetSchema = external_exports.enum([
10665
10777
  "540p",
10666
10778
  "580p",
10667
10779
  "720p",
10780
+ // Fal's MiniMax H3 resolution enum spells its low tier `768P`.
10781
+ "768P",
10668
10782
  "1080p",
10669
10783
  "1440p",
10670
10784
  "2160p",
@@ -11058,14 +11172,17 @@ var RunNodeBodySchema = external_exports.object({
11058
11172
  /** Explicit image URLs to include as inputs (merged with edge-resolved images). */
11059
11173
  imageUrls: external_exports.array(external_exports.string().url()).max(MAX_INPUT_IMAGES).optional(),
11060
11174
  /**
11061
- * Provider-specific voice id for audio TTS. Today only ElevenLabs is
11062
- * wired up when other providers ship their own voice catalogues the
11063
- * field set will grow (e.g. `openaiVoiceId`). Required when running an
11064
- * audio node in `text-to-speech` mode; ignored otherwise. Mode-specific
11065
- * validation lives in the run service because the schema can't see the
11066
- * resolved model→mode mapping.
11175
+ * ElevenLabs voice id for audio TTS. Superseded by `voiceId`, which works
11176
+ * for every provider; kept so already-deployed clients keep running.
11177
+ * Mode-specific validation lives in the run service because the schema
11178
+ * can't see the resolved model→mode mapping.
11067
11179
  */
11068
11180
  elevenLabsVoiceId: external_exports.string().trim().min(1).optional(),
11181
+ /**
11182
+ * Provider-agnostic voice selection, validated against the resolved
11183
+ * variant's voice capability. Takes precedence over `elevenLabsVoiceId`.
11184
+ */
11185
+ voiceId: external_exports.string().trim().min(1).optional(),
11069
11186
  /**
11070
11187
  * Team-owned custom voice. When set the backend resolves the underlying
11071
11188
  * provider voice id from the database and uses it in place of
@@ -11613,6 +11730,15 @@ var canvasContract = c7.router({
11613
11730
  pathParams: external_exports.object({ canvasId: external_exports.string().uuid() }),
11614
11731
  responses: { 200: CanvasResponseSchema }
11615
11732
  },
11733
+ getCanvasVersionFavorites: {
11734
+ method: "GET",
11735
+ path: "/canvases/:canvasId/version-favorites",
11736
+ pathParams: external_exports.object({ canvasId: external_exports.string().uuid() }),
11737
+ responses: {
11738
+ 200: CanvasVersionFavoritesResponseSchema,
11739
+ 404: MessageResponseSchema
11740
+ }
11741
+ },
11616
11742
  updateCanvas: {
11617
11743
  method: "PATCH",
11618
11744
  path: "/canvases/:canvasId",
@@ -12707,6 +12833,24 @@ var customFontContract = c8.router({
12707
12833
  }
12708
12834
  });
12709
12835
 
12836
+ // ../api-contract/src/audio-voices.ts
12837
+ var VoiceCatalogIdSchema = external_exports.enum(["elevenlabs", "fish-audio"]);
12838
+ var VoiceCapabilitySchema = external_exports.discriminatedUnion("source", [
12839
+ external_exports.object({
12840
+ source: external_exports.literal("static"),
12841
+ /** The provider's complete voice enum. */
12842
+ values: external_exports.array(external_exports.string()).readonly(),
12843
+ defaultVoice: external_exports.string()
12844
+ }),
12845
+ external_exports.object({
12846
+ source: external_exports.literal("catalog"),
12847
+ catalog: VoiceCatalogIdSchema,
12848
+ defaultVoice: external_exports.string().optional(),
12849
+ /** Team-owned cloned voices may be selected alongside the catalog. */
12850
+ supportsCustomVoices: external_exports.boolean().optional()
12851
+ })
12852
+ ]);
12853
+
12710
12854
  // ../api-contract/src/generation.ts
12711
12855
  var c9 = initContract();
12712
12856
  var GenerationJobStatusSchema = external_exports.enum([
@@ -12715,6 +12859,7 @@ var GenerationJobStatusSchema = external_exports.enum([
12715
12859
  "failed",
12716
12860
  "cancelled"
12717
12861
  ]);
12862
+ var FISH_AUDIO_MODEL = "fish-audio-s2.1-pro";
12718
12863
  var BetterFontSourceSchema = external_exports.enum(["custom", "google"]);
12719
12864
  var BetterFontSelectionSchema = external_exports.object({
12720
12865
  source: BetterFontSourceSchema,
@@ -12872,6 +13017,27 @@ var AutoModelDefaultsCategorySchema = external_exports.object({
12872
13017
  var AutoModelDefaultsResponseSchema = AutoModelDefaultsCategorySchema.extend({
12873
13018
  fast: AutoModelDefaultsCategorySchema
12874
13019
  });
13020
+ function sanitizeAgentAutoModelDefaultsCategory(category) {
13021
+ if (category.audio?.textToSpeech.model !== FISH_AUDIO_MODEL) {
13022
+ return category;
13023
+ }
13024
+ return {
13025
+ ...category,
13026
+ audio: {
13027
+ ...category.audio,
13028
+ textToSpeech: {
13029
+ model: ELEVENLABS_V3_MODEL_ID,
13030
+ variant: "text-to-speech"
13031
+ }
13032
+ }
13033
+ };
13034
+ }
13035
+ function sanitizeAgentAutoModelDefaults(defaults) {
13036
+ const standard = sanitizeAgentAutoModelDefaultsCategory(defaults);
13037
+ const fast = sanitizeAgentAutoModelDefaultsCategory(defaults.fast);
13038
+ if (standard === defaults && fast === defaults.fast) return defaults;
13039
+ return { ...standard, fast };
13040
+ }
12875
13041
  var ModelCostSchema = external_exports.discriminatedUnion("type", [
12876
13042
  external_exports.object({
12877
13043
  type: external_exports.literal("fixed"),
@@ -13001,6 +13167,8 @@ var ModelVariantResponseSchema = external_exports.object({
13001
13167
  defaultResolution: OutputResolutionSchema.nullable().optional(),
13002
13168
  featuredDescription: external_exports.string().nullable(),
13003
13169
  cost: ModelCostSchema.optional(),
13170
+ /** Selectable voices for audio variants, or null when none apply. */
13171
+ voices: VoiceCapabilitySchema.nullable().optional(),
13004
13172
  /**
13005
13173
  * Per-second credit multiplier applied to connected input video duration,
13006
13174
  * using the resolution-adjusted output per-second price as the base. Lets
@@ -13224,42 +13392,56 @@ var c10 = initContract();
13224
13392
  var TextNodeDataSchema = external_exports.object({
13225
13393
  title: external_exports.string(),
13226
13394
  mode: external_exports.string(),
13227
- prompt: external_exports.string()
13228
- }).passthrough();
13395
+ prompt: external_exports.string(),
13396
+ /** `getValidHandles` builds a text node's targets as `["text", ...this]`. */
13397
+ supportedInputs: external_exports.array(external_exports.string()).optional()
13398
+ });
13229
13399
  var ImageNodeDataSchema = external_exports.object({
13230
13400
  title: external_exports.string(),
13231
13401
  src: external_exports.string().optional(),
13232
13402
  mode: external_exports.string(),
13233
13403
  aspectRatio: external_exports.string().optional(),
13234
13404
  prompt: external_exports.string()
13235
- }).passthrough();
13405
+ });
13236
13406
  var VideoNodeDataSchema = external_exports.object({
13237
13407
  title: external_exports.string(),
13238
13408
  src: external_exports.string().optional(),
13239
13409
  mode: external_exports.string(),
13240
13410
  aspectRatio: external_exports.string().optional(),
13241
13411
  duration: external_exports.string().optional(),
13242
- prompt: external_exports.string()
13243
- }).passthrough();
13412
+ prompt: external_exports.string(),
13413
+ /**
13414
+ * Handle validation tests these by key PRESENCE (`hasModelCapabilityFlags`
13415
+ * in `canvas-handles.ts`) and treats them as one family, so dropping any one
13416
+ * key disables the whole model-flag branch rather than just that flag.
13417
+ * Declared together for that reason, not because every preset sets all four.
13418
+ */
13419
+ modelSupportsEndImage: external_exports.boolean().optional(),
13420
+ modelSupportsReferenceImage: external_exports.boolean().optional(),
13421
+ modelSupportsOptionalStartImage: external_exports.boolean().optional(),
13422
+ modelSupportsAudioInput: external_exports.boolean().optional()
13423
+ });
13244
13424
  var AudioNodeDataSchema = external_exports.object({
13245
13425
  title: external_exports.string(),
13246
13426
  src: external_exports.string().optional(),
13247
13427
  mode: external_exports.string().optional(),
13248
13428
  prompt: external_exports.string().optional(),
13249
13429
  voiceId: external_exports.string().optional()
13250
- }).passthrough();
13430
+ });
13251
13431
  var FileNodeDataSchema = external_exports.object({
13252
13432
  title: external_exports.string(),
13253
13433
  src: external_exports.string().optional(),
13254
- mediaType: external_exports.enum(["image", "video"])
13255
- }).passthrough();
13434
+ mediaType: external_exports.enum(["image", "video"]),
13435
+ /** Opts the preset viewer's file node into rendering an audio output. */
13436
+ showAudioOutput: external_exports.boolean().optional()
13437
+ });
13256
13438
  var CustomTextNodeDataSchema = external_exports.object({
13257
13439
  title: external_exports.string(),
13258
13440
  generatedText: external_exports.string().optional()
13259
- }).passthrough();
13441
+ });
13260
13442
  var GroupNodeDataSchema = external_exports.object({
13261
13443
  label: external_exports.string()
13262
- }).passthrough();
13444
+ });
13263
13445
  var SharedNodeFields = {
13264
13446
  key: external_exports.string(),
13265
13447
  width: external_exports.number().optional(),
@@ -14883,7 +15065,7 @@ function isMajorUpgrade(current, latest) {
14883
15065
  return l[0] > c17[0];
14884
15066
  }
14885
15067
  function shouldShowUpgradeNotice(ctx = {}) {
14886
- const current = ctx.current ?? "0.14.0";
15068
+ const current = ctx.current ?? "0.15.0";
14887
15069
  const latest = ctx.latest ?? serverLatestVersion;
14888
15070
  const env = ctx.env ?? process.env;
14889
15071
  const isTty = ctx.isTty ?? Boolean(process.stderr.isTTY);
@@ -14904,7 +15086,7 @@ Upgrade: npm install -g @melius-ai/cli@latest (or: brew update && brew upgrade
14904
15086
  function printUpgradeNoticeIfNeeded(ctx = {}) {
14905
15087
  try {
14906
15088
  if (!shouldShowUpgradeNotice(ctx)) return;
14907
- const current = ctx.current ?? "0.14.0";
15089
+ const current = ctx.current ?? "0.15.0";
14908
15090
  const latest = ctx.latest ?? serverLatestVersion;
14909
15091
  process.stderr.write(formatUpgradeNotice(current, latest));
14910
15092
  } catch {
@@ -16384,34 +16566,35 @@ function mapPresetLayoutNodeToDirectBody(layoutNode, nodeId, parentId, resolvedP
16384
16566
  title: getLayoutNodeTitle(layoutNode)
16385
16567
  };
16386
16568
  if (parentId !== void 0) body.groupId = parentId;
16387
- const prompt = resolvedPrompts?.get(layoutNode.key) ?? layoutNode.data.prompt;
16569
+ const data = layoutNode.data;
16570
+ const prompt = resolvedPrompts?.get(layoutNode.key) ?? ("prompt" in data ? data.prompt : void 0);
16388
16571
  if (typeof prompt === "string") {
16389
16572
  body.textPrompt = prompt;
16390
16573
  }
16391
- if (typeof layoutNode.data.generatedText === "string") {
16392
- body.text = layoutNode.data.generatedText;
16574
+ if ("generatedText" in data && typeof data.generatedText === "string") {
16575
+ body.text = data.generatedText;
16393
16576
  }
16394
- if (typeof layoutNode.data.aspectRatio === "string") {
16395
- body.outputAspectRatio = layoutNode.data.aspectRatio;
16577
+ if ("aspectRatio" in data && typeof data.aspectRatio === "string") {
16578
+ body.outputAspectRatio = data.aspectRatio;
16396
16579
  }
16397
- if (layoutNode.data.duration !== void 0) {
16398
- body.outputDuration = Number(layoutNode.data.duration);
16580
+ if ("duration" in data && data.duration !== void 0) {
16581
+ body.outputDuration = Number(data.duration);
16399
16582
  }
16400
16583
  if (layoutNode.autoModel) {
16401
16584
  body.modelConfig = layoutNode.autoModel;
16402
16585
  }
16403
- if (layoutNode.data.mediaType === "image" || layoutNode.data.mediaType === "video") {
16404
- body.mediaType = layoutNode.data.mediaType;
16586
+ if ("mediaType" in data && (data.mediaType === "image" || data.mediaType === "video")) {
16587
+ body.mediaType = data.mediaType;
16405
16588
  }
16406
- if (typeof layoutNode.data.voiceId === "string") {
16407
- body.voiceId = layoutNode.data.voiceId;
16589
+ if ("voiceId" in data && typeof data.voiceId === "string") {
16590
+ body.voiceId = data.voiceId;
16408
16591
  }
16409
16592
  return body;
16410
16593
  }
16411
16594
  function resolvePresetMentions(layout, keyToId) {
16412
16595
  const titleToId = /* @__PURE__ */ new Map();
16413
16596
  for (const node of layout.nodes) {
16414
- const title = node.data.title ?? node.data.label;
16597
+ const title = readLayoutNodeName(node);
16415
16598
  const nodeId = keyToId.get(node.key);
16416
16599
  if (title && nodeId) {
16417
16600
  titleToId.set(title.toLowerCase(), nodeId);
@@ -16419,7 +16602,7 @@ function resolvePresetMentions(layout, keyToId) {
16419
16602
  }
16420
16603
  const resolved = /* @__PURE__ */ new Map();
16421
16604
  for (const node of layout.nodes) {
16422
- const prompt = node.data.prompt;
16605
+ const prompt = "prompt" in node.data ? node.data.prompt : void 0;
16423
16606
  if (!prompt) continue;
16424
16607
  const rewritten = prompt.replace(
16425
16608
  MENTION_RE,
@@ -16442,8 +16625,12 @@ function getNodeWidth(nodeCfg) {
16442
16625
  function getNodeHeight(nodeCfg) {
16443
16626
  return nodeCfg.height ?? getEstimatedHeight(nodeCfg.type);
16444
16627
  }
16628
+ function readLayoutNodeName(layoutNode) {
16629
+ if ("title" in layoutNode.data) return layoutNode.data.title;
16630
+ return layoutNode.data.label;
16631
+ }
16445
16632
  function getLayoutNodeTitle(layoutNode) {
16446
- return layoutNode.data.title ?? layoutNode.data.label ?? layoutNode.type.charAt(0).toUpperCase() + layoutNode.type.slice(1);
16633
+ return readLayoutNodeName(layoutNode) ?? layoutNode.type.charAt(0).toUpperCase() + layoutNode.type.slice(1);
16447
16634
  }
16448
16635
  function groupByColumn(nodes) {
16449
16636
  const hasColumns = nodes.some((n) => n.column !== void 0);
@@ -16990,6 +17177,18 @@ function resolveNodeIds2(canvasId, nodeIds) {
16990
17177
 
16991
17178
  // src/lib/validation.ts
16992
17179
  function validateModelConfig(model, variant) {
17180
+ if (model === FISH_AUDIO_MODEL) {
17181
+ writeError(
17182
+ formatError(
17183
+ "USAGE_ERROR",
17184
+ `${FISH_AUDIO_MODEL} is not available in the CLI`,
17185
+ {
17186
+ suggestion: "Choose a model returned by: mel model list --category audio"
17187
+ }
17188
+ ),
17189
+ EXIT_USAGE_ERROR
17190
+ );
17191
+ }
16993
17192
  if (model && variant) return { model, variant };
16994
17193
  if (!model && !variant) return void 0;
16995
17194
  writeError(
@@ -18832,7 +19031,10 @@ Examples:
18832
19031
  handleApiError(result.status, result.body);
18833
19032
  }
18834
19033
  const body = result.body;
18835
- writeJson(body.models, getOutputOpts());
19034
+ writeJson(
19035
+ body.models.filter((entry) => entry.name !== FISH_AUDIO_MODEL),
19036
+ getOutputOpts()
19037
+ );
18836
19038
  });
18837
19039
  model.command("defaults").description("Show which model is used when no --model is specified").addHelpText(
18838
19040
  "after",
@@ -18849,7 +19051,10 @@ Examples:
18849
19051
  if (result.status !== 200) {
18850
19052
  handleApiError(result.status, result.body);
18851
19053
  }
18852
- writeJson(result.body, getOutputOpts());
19054
+ writeJson(
19055
+ sanitizeAgentAutoModelDefaults(result.body),
19056
+ getOutputOpts()
19057
+ );
18853
19058
  });
18854
19059
  }
18855
19060
 
@@ -20100,7 +20305,7 @@ function withDefaultHelp(args) {
20100
20305
  }
20101
20306
  function createProgram() {
20102
20307
  const program2 = new Command();
20103
- program2.name("mel").description("Mel \u2014 Melius agent CLI").version("0.14.0").showSuggestionAfterError(true).option("--json", "Force JSON output (default)").option("--text", "Human-readable output").option(
20308
+ program2.name("mel").description("Mel \u2014 Melius agent CLI").version("0.15.0").showSuggestionAfterError(true).option("--json", "Force JSON output (default)").option("--text", "Human-readable output").option(
20104
20309
  "--fields <fields>",
20105
20310
  "Select specific output fields (comma-separated)"
20106
20311
  ).option("--quiet", "Suppress output, exit code only").option("--verbose", "Log request/response metadata to stderr").addHelpText(
package/dist/src/index.js CHANGED
@@ -2,7 +2,7 @@ import { createRequire } from 'node:module'; const require = createRequire(impor
2
2
  import {
3
3
  createProgram,
4
4
  withDefaultHelp
5
- } from "../chunk-RTPRU2JD.js";
5
+ } from "../chunk-VOIPEX54.js";
6
6
  export {
7
7
  createProgram,
8
8
  withDefaultHelp
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@melius-ai/cli",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "The Melius command-line interface — create canvases and run AI image/video generations from your terminal",
5
5
  "keywords": [
6
6
  "ai",