Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
* text=auto

.gitattributes text eol=lf
*.cmd text eol=crlf
*.mjs text eol=lf
*.json text eol=lf
*.md text eol=lf

plugins/minimax-h3-cloud/scripts/h3-cloud text eol=lf
plugins/minimax-h3-cloud/scripts/h3-onboard text eol=lf
plugins/minimax-h3-cloud/scripts/h3-provision text eol=lf
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

## 前置条件

- macOS 或 Linux;
- Windows 10/11、macOS 或 Linux;
- 支持插件的 Codex;
- Node.js 20 或更高版本;
- `ssh` 和 `ffprobe`;
Expand All @@ -29,7 +29,21 @@
可以通过 PyPI 安装 CompShare CLI:

```bash
python3 -m pip install --upgrade compshare-cli
python -m pip install --upgrade compshare-cli
compshare --version
Comment on lines +32 to +33
```

如果当前 CompShare CLI 版本因 Typer/Click 依赖组合而无法启动,可使用已验证的兼容版本:

```bash
python -m pip install --upgrade compshare-cli "typer==0.20.1" "click==8.2.1"
```

Windows 还需要启用系统的 OpenSSH Client,并确保 `ssh.exe`、`ffprobe.exe`、`node.exe`、`compshare.exe` 及 `compshare-ssh-askpass.exe` 可从 `PATH` 找到。可以在 PowerShell 中检查:

```powershell
Get-Command node, ssh, ffprobe, compshare, compshare-ssh-askpass
node --version
compshare --version
```

Expand All @@ -50,7 +64,14 @@ codex plugin add minimax-h3-cloud@sac-y-minimax-h3
4. 确认视频参数与预计费用;
5. 自动生成、在 Codex 中播放并提供 MP4 下载。

插件不会要求把 API Key 发到对话中。凭证由 CompShare CLI 保存在用户本机;插件配置默认写入 `~/.config/minimax-h3-cloud/config.json`,视频默认写入 `~/.local/share/minimax-h3-cloud/outputs/`。这两个位置都在插件安装目录之外,升级插件不会覆盖用户数据。
插件不会要求把 API Key 发到对话中。凭证由 CompShare CLI 保存在用户本机;配置和视频都位于插件安装目录之外,升级插件不会覆盖用户数据。

| 系统 | 默认配置 | 默认视频目录 |
|---|---|---|
| Windows | `%APPDATA%\minimax-h3-cloud\config.json` | `%LOCALAPPDATA%\minimax-h3-cloud\outputs\` |
| macOS / Linux | `~/.config/minimax-h3-cloud/config.json` | `~/.local/share/minimax-h3-cloud/outputs/` |

Windows 原生入口为 `scripts\h3-onboard.cmd`、`scripts\h3-provision.cmd` 和 `scripts\h3-cloud.cmd`;macOS/Linux 继续使用同名无扩展名脚本。高级用户可通过 `COMPSHARE_CLI_PATH`、`MINIMAX_H3_SSH_PATH` 和 `MINIMAX_H3_SSH_ASKPASS_PATH` 指定自定义可执行文件路径。

## 费用与资源

Expand Down
8 changes: 5 additions & 3 deletions plugins/minimax-h3-cloud/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "minimax-h3-cloud",
"version": "0.1.0",
"version": "0.2.0",
"description": "\u4ece Codex \u8c03\u7528\u53ef\u66ff\u6362\u7684\u4e91\u7aef GPU \u73af\u5883\u751f\u6210 MiniMax H3 \u89c6\u9891\uff0c\u5e76\u81ea\u52a8\u56de\u6536\u7b97\u529b\u3002",
"author": {
"name": "Sac-Y",
Expand All @@ -13,7 +13,8 @@
"minimax-h3",
"video",
"comfyui",
"gpu"
"gpu",
"windows"
],
"skills": "./skills/",
"interface": {
Expand All @@ -32,7 +33,8 @@
"Keyframe image-to-video",
"1\u20139 reference-images-to-video",
"Prompt recovery without duplicate submission",
"Cloud GPU lifecycle"
"Cloud GPU lifecycle",
"Native Windows, macOS, and Linux launchers"
],
"defaultPrompt": [
"\u751f\u6210\u4e00\u6bb5 MiniMax H3 \u89c6\u9891\uff1a16:9 \u6a2a\u5c4f\uff0c5 \u79d2\uff0c0.4MP\uff08\u7ea6 480P\uff09\u3002",
Expand Down
68 changes: 62 additions & 6 deletions plugins/minimax-h3-cloud/runtime/src/compshare-cli.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { execFile } from "node:child_process";
import { dirname, join } from "node:path";
import { promisify } from "node:util";
import {
environmentValue,
findExecutableOnPath,
} from "./executable-paths.mjs";

const execFileAsync = promisify(execFile);

Expand All @@ -14,7 +19,7 @@ export class CompShareCliError extends Error {
function parseEnvelope(stdout) {
let envelope;
try {
envelope = JSON.parse(stdout);
envelope = JSON.parse(String(stdout).replace(/^\uFEFF/u, ""));
} catch {
throw new CompShareCliError("compshare-cli 没有返回有效 JSON", {
code: "COMPSHARE_INVALID_JSON",
Expand All @@ -34,10 +39,55 @@ function parseEnvelope(stdout) {
return envelope.data;
}

export async function runCompShareCli(args, { timeoutMs = 620_000 } = {}) {
export function resolveCompShareCliPath({
env = process.env,
platform = process.platform,
} = {}) {
const override = environmentValue(env, "COMPSHARE_CLI_PATH")?.trim();
if (override) return override;
const command = platform === "win32" ? "compshare.exe" : "compshare";
return findExecutableOnPath(command, { env, platform }) ?? command;
}

export function resolveCompShareAskpassPath({
env = process.env,
platform = process.platform,
} = {}) {
const override = environmentValue(
env,
"MINIMAX_H3_SSH_ASKPASS_PATH",
)?.trim();
if (override) return override;
Comment on lines +56 to +60

const command =
platform === "win32"
? "compshare-ssh-askpass.exe"
: "compshare-ssh-askpass";
const located = findExecutableOnPath(command, { env, platform });
if (located) return located;

const cliPath = resolveCompShareCliPath({ env, platform });
if (/[\\/]/.test(cliPath)) {
const sibling = join(dirname(cliPath), command);
return findExecutableOnPath(sibling, { env, platform });
}
return undefined;
}

export async function runCompShareCli(
args,
{
timeoutMs = 620_000,
env = process.env,
platform = process.platform,
executable = resolveCompShareCliPath({ env, platform }),
execFileImpl = execFileAsync,
} = {},
) {
try {
const { stdout } = await execFileAsync("compshare", args, {
const { stdout } = await execFileImpl(executable, args, {
encoding: "utf8",
env,
maxBuffer: 4 * 1024 * 1024,
timeout: timeoutMs,
});
Expand All @@ -49,8 +99,14 @@ export async function runCompShareCli(args, { timeoutMs = 620_000 } = {}) {
return parseEnvelope(error.stdout);
}

throw new CompShareCliError(error?.message ?? String(error), {
code: error?.code ?? "COMPSHARE_PROCESS_ERROR",
});
const missing = error?.code === "ENOENT";
throw new CompShareCliError(
missing
? `找不到 CompShare CLI:${executable}。请安装 compshare-cli 并确认其 Scripts/bin 目录已加入 PATH,或设置 COMPSHARE_CLI_PATH。`
: error?.message ?? String(error),
{
code: missing ? "COMPSHARE_CLI_NOT_FOUND" : error?.code ?? "COMPSHARE_PROCESS_ERROR",
},
);
}
}
37 changes: 37 additions & 0 deletions plugins/minimax-h3-cloud/runtime/src/executable-paths.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { existsSync } from "node:fs";
import { delimiter, extname, isAbsolute, join } from "node:path";

export function environmentValue(env, name) {
if (env[name] !== undefined) return env[name];
const matchedKey = Object.keys(env).find(
(candidate) => candidate.toLowerCase() === name.toLowerCase(),
);
return matchedKey ? env[matchedKey] : undefined;
}

export function findExecutableOnPath(
command,
{ env = process.env, platform = process.platform } = {},
) {
if (!command?.trim()) return undefined;
if (isAbsolute(command) || /[\\/]/.test(command)) {
return existsSync(command) ? command : undefined;
}

const pathValue = environmentValue(env, "PATH");
if (!pathValue) return undefined;
const suffixes =
platform === "win32" && !extname(command)
? (environmentValue(env, "PATHEXT") || ".COM;.EXE;.BAT;.CMD")
.split(";")
.filter(Boolean)
: [""];

for (const directory of pathValue.split(delimiter).filter(Boolean)) {
for (const suffix of suffixes) {
const candidate = join(directory.replace(/^"|"$/g, ""), `${command}${suffix}`);
if (existsSync(candidate)) return candidate;
}
}
return undefined;
}
Loading