@mrgoonie/multix 1.0.1 → 1.0.2
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/CHANGELOG.md +7 -0
- package/dist/cli.js +50 -2
- package/package.json +1 -1
- package/skill/SKILL.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.0.2](https://github.com/mrgoonie/multix-cli/compare/v1.0.1...v1.0.2) (2026-10-11)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
* **fal:** only send the key to trusted queue status and response URLs ([#112](https://github.com/mrgoonie/multix-cli/issues/112)) ([92e61c5](https://github.com/mrgoonie/multix-cli/commit/92e61c547999e0bb30f1f4be6d9bbc1ce8226d24))
|
|
14
|
+
|
|
8
15
|
## [1.0.1](https://github.com/mrgoonie/multix-cli/compare/v1.0.0...v1.0.1) (2026-10-11)
|
|
9
16
|
|
|
10
17
|
|
package/dist/cli.js
CHANGED
|
@@ -4520,6 +4520,7 @@ var FAL_DEFAULTS = {
|
|
|
4520
4520
|
};
|
|
4521
4521
|
|
|
4522
4522
|
// src/providers/fal/run-helpers.ts
|
|
4523
|
+
init_errors();
|
|
4523
4524
|
import fs18 from "fs";
|
|
4524
4525
|
import path21 from "path";
|
|
4525
4526
|
init_redact();
|
|
@@ -4528,6 +4529,34 @@ init_redact();
|
|
|
4528
4529
|
init_errors();
|
|
4529
4530
|
init_errors();
|
|
4530
4531
|
init_redact();
|
|
4532
|
+
var FAL_QUEUE_HOST = "queue.fal.run";
|
|
4533
|
+
function parseUrl(url) {
|
|
4534
|
+
try {
|
|
4535
|
+
return new URL(url);
|
|
4536
|
+
} catch {
|
|
4537
|
+
return void 0;
|
|
4538
|
+
}
|
|
4539
|
+
}
|
|
4540
|
+
function normalizedHost(u) {
|
|
4541
|
+
return u.hostname.toLowerCase().replace(/\.$/, "");
|
|
4542
|
+
}
|
|
4543
|
+
function normalizedOrigin(u) {
|
|
4544
|
+
return `${u.protocol}//${normalizedHost(u)}:${u.port}`;
|
|
4545
|
+
}
|
|
4546
|
+
function assertTrustedFalUrl(url, baseUrl) {
|
|
4547
|
+
const target = parseUrl(url);
|
|
4548
|
+
if (!target) {
|
|
4549
|
+
throw new ProviderError("Refusing to send the fal key to a malformed URL", "fal");
|
|
4550
|
+
}
|
|
4551
|
+
const base = parseUrl(baseUrl);
|
|
4552
|
+
if (base && normalizedOrigin(target) === normalizedOrigin(base)) return;
|
|
4553
|
+
const host = normalizedHost(target);
|
|
4554
|
+
if (target.protocol === "https:" && host === FAL_QUEUE_HOST && target.port === "") return;
|
|
4555
|
+
throw new ProviderError(
|
|
4556
|
+
`Refusing to send the fal key to ${host || "this URL"}: not https://${FAL_QUEUE_HOST} or the FAL_BASE_URL origin`,
|
|
4557
|
+
"fal"
|
|
4558
|
+
);
|
|
4559
|
+
}
|
|
4531
4560
|
function requireFalKey() {
|
|
4532
4561
|
const key = resolveRoutedKey(FAL_ROUTING);
|
|
4533
4562
|
if (!key) {
|
|
@@ -4549,10 +4578,22 @@ var FalClient = class {
|
|
|
4549
4578
|
async request(path57, opts = {}) {
|
|
4550
4579
|
const base = this.baseUrl.replace(/\/$/, "");
|
|
4551
4580
|
const suffix = path57.startsWith("/") ? path57 : `/${path57}`;
|
|
4552
|
-
return this.
|
|
4581
|
+
return this.send(base + suffix, opts);
|
|
4553
4582
|
}
|
|
4554
|
-
/**
|
|
4583
|
+
/**
|
|
4584
|
+
* Same auth/headers as `request`, but `url` is used verbatim (e.g. a
|
|
4585
|
+
* status_url/response_url returned by submit). The URL must pass
|
|
4586
|
+
* {@link assertTrustedFalUrl} before the key is sent.
|
|
4587
|
+
*/
|
|
4555
4588
|
async requestAbsolute(url, opts = {}) {
|
|
4589
|
+
assertTrustedFalUrl(url, this.baseUrl);
|
|
4590
|
+
return this.send(url, opts);
|
|
4591
|
+
}
|
|
4592
|
+
/** Throws a ProviderError when `url` may not receive the key (see {@link assertTrustedFalUrl}). */
|
|
4593
|
+
assertTrustedUrl(url) {
|
|
4594
|
+
assertTrustedFalUrl(url, this.baseUrl);
|
|
4595
|
+
}
|
|
4596
|
+
async send(url, opts) {
|
|
4556
4597
|
opts.logger?.debug(`${opts.method ?? "GET"} ${redactUrl(url)}`);
|
|
4557
4598
|
return httpJson({
|
|
4558
4599
|
url,
|
|
@@ -4620,6 +4661,13 @@ async function submitAndWait(opts) {
|
|
|
4620
4661
|
const submitRes = await client.post(submitPath(model), input, logger);
|
|
4621
4662
|
const requestId = submitRes.request_id;
|
|
4622
4663
|
logger.debug(`request_id: ${requestId}`);
|
|
4664
|
+
for (const field of ["status_url", "response_url"]) {
|
|
4665
|
+
const url = submitRes[field];
|
|
4666
|
+
if (typeof url !== "string" || url === "") {
|
|
4667
|
+
throw new ProviderError(`fal submit response is missing ${field}`, "fal");
|
|
4668
|
+
}
|
|
4669
|
+
client.assertTrustedUrl(url);
|
|
4670
|
+
}
|
|
4623
4671
|
logger.info("Polling for completion...");
|
|
4624
4672
|
const waitTimeoutMs = opts.waitTimeoutMs ?? 48e4;
|
|
4625
4673
|
const intervalMs = opts.pollIntervalMs ?? 3e3;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrgoonie/multix",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "AI multimodal CLI — OpenAI, Gemini, MiniMax, OpenRouter, Leonardo, BytePlus, ElevenLabs, fal.ai, Atlas Cloud, Replicate, HeyGen, ffmpeg, ImageMagick, doc-to-md",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/skill/SKILL.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: multix
|
|
3
3
|
description: AI multimodal CLI — generate and edit images (OpenAI, Codex driver, Gemini Nano Banana, Imagen, MiniMax, OpenRouter, Leonardo, BytePlus Seedream, Cloudflare Workers AI FLUX.1 Schnell, fal.ai FLUX, Replicate FLUX), generate video (Gemini Veo, MiniMax Hailuo, OpenRouter via Veo/Seedance/Kling, Leonardo via Motion/Veo/Kling/Hailuo/Seedance/LTX, BytePlus Seedance, Cloudflare AI Gateway via Replicate, fal.ai queue models, Replicate direct API models incl. P-Video, HeyGen Video Agent and scripted avatar videos), video translation and lipsync (HeyGen), TTS/STT/music (OpenAI, Gemini Flash TTS incl. Gemini 3.8 with delivery-style control, MiniMax, Cloudflare Workers AI MeloTTS, ElevenLabs), 3D models (BytePlus Hyper3D/Hitem3d), analyze/transcribe media, convert documents to Markdown, optimize media via ffmpeg/ImageMagick, and self-update the CLI. Use whenever the user wants to create, edit, or transform images/video/audio/3D/documents from a CLI, mentions any of: OpenAI, Codex image driver, image-to-image, i2i, image edit, watercolor/cyberpunk style transfer, reference image, OpenRouter, Nano Banana, Flux, Seedream, Veo, Hailuo, Seedance, Kling, Cloudflare Workers AI, AI Gateway, fal.ai, Atlas Cloud, Replicate, replicate.com models, Replicate predictions, HeyGen, avatar video, talking head, Video Agent, video translation, dubbing, lipsync, video generation, text-to-video, image-to-video, i2v, ElevenLabs voice cloning, updating/upgrading multix, or asks for batch media optimization.
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.2 # x-release-please-version
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# multix — AI Multimodal CLI
|