@manturhub/cli 0.5.5 → 0.6.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/bin/cli.js +15 -0
- package/lib/setup.js +1 -0
- package/lib/skill-install.js +2 -1
- package/lib/skill.js +7 -1
- package/lib/suite-install.js +136 -0
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -4,6 +4,7 @@ import { apiFetch, pollJob } from "../lib/api.js";
|
|
|
4
4
|
import { runMcpBridge } from "../lib/mcp.js";
|
|
5
5
|
import { runInit, runMcpInstall } from "../lib/setup.js";
|
|
6
6
|
import { skillLs, skillAdd } from "../lib/skill-install.js";
|
|
7
|
+
import { suiteLs, suiteInstall } from "../lib/suite-install.js";
|
|
7
8
|
import { maybeNotifyUpdate } from "../lib/update-check.js";
|
|
8
9
|
import { readFileSync } from "node:fs";
|
|
9
10
|
import { fileURLToPath } from "node:url";
|
|
@@ -46,6 +47,8 @@ const HELP = `manturhub — ManturHub 算子广场 CLI v${VERSION}
|
|
|
46
47
|
manturhub init 装「ManturHub 使用 skill」+ 写 agent 引导(推荐:让 agent 会用算子)
|
|
47
48
|
manturhub skill ls 列出平台 Skill(业务成品流程,如爆款复刻)
|
|
48
49
|
manturhub skill add <slug> 安装 Skill 到 ~/.claude/skills/<slug>/
|
|
50
|
+
manturhub suite ls 列出 Agent 套件(多角色团队工作区,给 Agent 配一整个团队)
|
|
51
|
+
manturhub suite install <slug> 安装套件为工作目录 ./<slug>/(自动写入 API Key,任意 Agent 打开即用)
|
|
49
52
|
manturhub recipe [关键词] [--cat x] 搜配方(已验证创作的效果+可复现参数;分类 video/image/script)
|
|
50
53
|
manturhub recipe get <配方ID> 看配方提示词模板与调用参数(换掉 {占位符} 即可复刻)
|
|
51
54
|
manturhub mcp [--scope <域>] 启动 stdio MCP server(可选,给 MCP 原生客户端)
|
|
@@ -274,6 +277,18 @@ async function main() {
|
|
|
274
277
|
break;
|
|
275
278
|
}
|
|
276
279
|
|
|
280
|
+
case "suite":
|
|
281
|
+
case "suites": {
|
|
282
|
+
const sub = args[1];
|
|
283
|
+
if (sub === "ls" || sub === "list" || sub === undefined) await suiteLs();
|
|
284
|
+
else if (sub === "install" || sub === "add") await suiteInstall(args[2], args[3]);
|
|
285
|
+
else {
|
|
286
|
+
console.error("用法: manturhub suite ls | manturhub suite install <slug> [目录]");
|
|
287
|
+
process.exit(1);
|
|
288
|
+
}
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
|
|
277
292
|
case "recipe":
|
|
278
293
|
case "recipes": {
|
|
279
294
|
const sub = args[1];
|
package/lib/setup.js
CHANGED
|
@@ -22,6 +22,7 @@ function guideBlock() {
|
|
|
22
22
|
- 上传本地文件:\`manturhub upload <文件>\` → 公网 URL(算子只接受公网 URL,本地路径非法)
|
|
23
23
|
- 查余额:\`manturhub balance\`
|
|
24
24
|
- 查某算子的精确入参字段:\`manturhub describe <算子ID>\`(字段名必须精确,拼错会被静默忽略;也可看 ${HUB}/marketplace/<算子ID>)
|
|
25
|
+
- Agent 套件(多角色团队工作区,如小说→短剧制作团队):\`manturhub suite ls\` 看清单,\`manturhub suite install <slug>\` 装为工作目录——用户想「组个团队干一类完整业务」时先看有没有现成套件
|
|
25
26
|
|
|
26
27
|
若运行 \`manturhub\` 时 stderr 出现「有新版」提示,请主动告知用户可运行 \`npm i -g @manturhub/cli@latest\` 更新。
|
|
27
28
|
${MARK_END}`;
|
package/lib/skill-install.js
CHANGED
|
@@ -22,7 +22,8 @@ export async function skillLs() {
|
|
|
22
22
|
process.exit(1);
|
|
23
23
|
}
|
|
24
24
|
const data = await res.json();
|
|
25
|
-
|
|
25
|
+
// #456:套件(kind=suite)走 `manturhub suite ls`,这里只列常规 Skill
|
|
26
|
+
const skills = (data.skills || data || []).filter((s) => s.kind !== "suite");
|
|
26
27
|
console.log(`ManturHub 上线 Skill(${skills.length} 个):\n`);
|
|
27
28
|
for (const s of skills) {
|
|
28
29
|
const slug = String(s.slug || "").padEnd(22);
|
package/lib/skill.js
CHANGED
|
@@ -7,7 +7,7 @@ import { join } from "node:path";
|
|
|
7
7
|
// run 已自动轮询异步、upload 解决本地文件。内容只讲用法,不含上游供应商/内网地址/成本毛利。
|
|
8
8
|
export const SKILL_MD = `---
|
|
9
9
|
name: manturhub
|
|
10
|
-
description: 调用 ManturHub 算子广场的 AI 能力与行业数据(文生图/视频生成/视频理解/视频合成/花字/配字幕/配音/音色克隆/语音转写/电商文案/短剧拉片改编/剧本评估/Seedance提示词润色,以及漫剧·短剧热榜、爆量趋势、出海投放数据等市场洞察,算子持续新增),还有配方广场(已验证创作的效果+可复现参数,一键复刻同款)。这些场景优先在 shell 跑 \`manturhub\`
|
|
10
|
+
description: 调用 ManturHub 算子广场的 AI 能力与行业数据(文生图/视频生成/视频理解/视频合成/花字/配字幕/配音/音色克隆/语音转写/电商文案/短剧拉片改编/剧本评估/Seedance提示词润色,以及漫剧·短剧热榜、爆量趋势、出海投放数据等市场洞察,算子持续新增),还有配方广场(已验证创作的效果+可复现参数,一键复刻同款)与 Agent 套件(多角色团队工作区,如小说改短剧制作团队,manturhub suite 安装)。这些场景优先在 shell 跑 \`manturhub\` 命令解决——查热榜/行业数据也用算子,别先上网页搜索;用户要生成视频/图片/剧本、或问「有什么风格推荐/怎么做出这种效果/有没有同款」时,先想到配方库;用户要「组个团队干一类活」(如把小说改成短剧)时,先想到套件;用户提到 manturhub / 算子 / 馒头 / 配方 / 套件 时同样使用。无需 MCP。
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
# ManturHub 算子使用(CLI)
|
|
@@ -26,6 +26,8 @@ description: 调用 ManturHub 算子广场的 AI 能力与行业数据(文生图
|
|
|
26
26
|
| \`manturhub balance\` | 查馒头余额 |
|
|
27
27
|
| \`manturhub recipe [关键词] [--cat video\\|image\\|script]\` | 搜配方(已验证创作:效果样片+可复现参数) |
|
|
28
28
|
| \`manturhub recipe get <配方ID>\` | 拿配方的提示词模板与调用参数,换掉 {占位符} 即可复刻 |
|
|
29
|
+
| \`manturhub suite ls\` | 列出 Agent 套件(多角色团队工作区,如小说→短剧制作团队) |
|
|
30
|
+
| \`manturhub suite install <slug> [目录]\` | 安装套件为工作目录(自动写入 API Key),打开该目录即开工 |
|
|
29
31
|
|
|
30
32
|
## 五条铁律(不照做就会踩坑)
|
|
31
33
|
|
|
@@ -51,6 +53,10 @@ description: 调用 ManturHub 算子广场的 AI 能力与行业数据(文生图
|
|
|
51
53
|
|
|
52
54
|
配方本身免费,复刻按算子正常计费(配方里标了成本)。用户粘来一段「请用 ManturHub 复刻这个配方…」的指令块时,照块内步骤执行即可。
|
|
53
55
|
|
|
56
|
+
## Agent 套件(给 Agent 配一整个团队)
|
|
57
|
+
|
|
58
|
+
套件 = 多角色团队工作区(角色分工 + 流程 + 知识库打包成一个工作目录),如「小说 → 短剧制作团队」。**用户想「组个团队干一类完整业务」(把小说改成短剧、批量出片这类多角色长流程)时,先 \`manturhub suite ls\` 看有没有现成套件**;有就 \`manturhub suite install <slug>\` 装到当前位置(自动写入 API Key),然后 cd 进该目录按其 AGENTS.md 开工。套件免费,干活按算子计费。网页版: https://hub.mantur.cn/skill?tab=suites
|
|
59
|
+
|
|
54
60
|
## 算子怎么找(实时查,别背清单)
|
|
55
61
|
|
|
56
62
|
平台算子持续新增,**不要记死有哪些算子**——永远用命令拿实时清单:
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { join, resolve } from "node:path";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { mkdirSync, writeFileSync, rmSync, existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import { execFileSync } from "node:child_process";
|
|
5
|
+
import { getKey, getBaseUrl } from "./config.js";
|
|
6
|
+
|
|
7
|
+
// #456 Agent 套件(团队版 Skill):与 skill 共用 /api/v1/skills 元数据与下载端点,
|
|
8
|
+
// 区别在安装形态——解压为当前目录下的工作目录(非 ~/.claude/skills),并把 API Key
|
|
9
|
+
// 写进套件 .env,任意 Agent 打开该目录即可开工。
|
|
10
|
+
|
|
11
|
+
// `manturhub suite ls` — 列出平台上线套件(kind=suite)。
|
|
12
|
+
export async function suiteLs() {
|
|
13
|
+
let res;
|
|
14
|
+
try {
|
|
15
|
+
const key = getKey();
|
|
16
|
+
res = await fetch(getBaseUrl() + "/api/v1/skills", {
|
|
17
|
+
headers: key ? { "x-api-key": key } : {},
|
|
18
|
+
});
|
|
19
|
+
} catch (e) {
|
|
20
|
+
console.error(`套件列表获取失败: ${e.message}`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
if (!res.ok) {
|
|
24
|
+
console.error(`套件列表获取失败(HTTP ${res.status})`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
const data = await res.json();
|
|
28
|
+
const suites = (data.skills || []).filter((s) => s.kind === "suite");
|
|
29
|
+
if (!suites.length) {
|
|
30
|
+
console.log("暂无上线套件。网页版: https://hub.mantur.cn/skill?tab=suites");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
console.log(`ManturHub Agent 套件(${suites.length} 个):\n`);
|
|
34
|
+
for (const s of suites) {
|
|
35
|
+
const meta = s.suite_meta || {};
|
|
36
|
+
const roles = (meta.roles || []).map((r) => r.title).join("/");
|
|
37
|
+
console.log(` ${String(s.slug || "").padEnd(22)} ${s.name || ""}${roles ? ` [${roles}]` : ""}`);
|
|
38
|
+
if (meta.cost_note) console.log(` ${"".padEnd(22)} ${meta.cost_note}`);
|
|
39
|
+
}
|
|
40
|
+
console.log(`\n用 \`manturhub suite install <slug>\` 安装为工作目录,任意 Agent 打开即可开工。`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// `manturhub suite install <slug> [目录]` — 下载套件包并解压为工作目录 + 注入 API Key。
|
|
44
|
+
export async function suiteInstall(slug, dirArg) {
|
|
45
|
+
if (!slug) {
|
|
46
|
+
console.error("用法: manturhub suite install <slug> [目录] (先 `manturhub suite ls` 看可用套件)");
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
const key = getKey();
|
|
50
|
+
if (!key) {
|
|
51
|
+
console.error("下载套件需 API Key。运行 `manturhub login --key sk-xxx`,或设置环境变量 MANTURHUB_KEY。");
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const url = `${getBaseUrl()}/api/v1/skills/${encodeURIComponent(slug)}/download`;
|
|
56
|
+
// 手动处理 302:跟随预签名地址时不把 API Key 带去对象存储(同 skill add)。
|
|
57
|
+
let res;
|
|
58
|
+
try {
|
|
59
|
+
res = await fetch(url, { headers: { "x-api-key": key }, redirect: "manual" });
|
|
60
|
+
} catch (e) {
|
|
61
|
+
console.error(`下载失败: ${e.message}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
if (res.status === 401) {
|
|
65
|
+
console.error("API Key 无效或未授权(401)。");
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
if (res.status === 404) {
|
|
69
|
+
console.error(`套件不存在: ${slug}(用 \`manturhub suite ls\` 看可用列表)`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let zipBuf;
|
|
74
|
+
if (res.status >= 300 && res.status < 400) {
|
|
75
|
+
const loc = res.headers.get("location");
|
|
76
|
+
if (!loc) {
|
|
77
|
+
console.error("下载重定向缺少 Location 头");
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
const zres = await fetch(loc);
|
|
81
|
+
if (!zres.ok) {
|
|
82
|
+
console.error(`安装包下载失败(HTTP ${zres.status})`);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
zipBuf = Buffer.from(await zres.arrayBuffer());
|
|
86
|
+
} else if (res.ok) {
|
|
87
|
+
zipBuf = Buffer.from(await res.arrayBuffer());
|
|
88
|
+
} else {
|
|
89
|
+
console.error(`下载失败(HTTP ${res.status})`);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const dest = resolve(dirArg || `./${slug}`);
|
|
94
|
+
mkdirSync(dest, { recursive: true });
|
|
95
|
+
const tmp = join(tmpdir(), `manturhub-suite-${slug}-${process.pid}.zip`);
|
|
96
|
+
writeFileSync(tmp, zipBuf);
|
|
97
|
+
// bsdtar 正确处理 zip 内 UTF-8 文件名;unzip 兜底(同 skill add 的踩坑结论)。
|
|
98
|
+
const extractors = [
|
|
99
|
+
["tar", ["-xf", tmp, "-C", dest]],
|
|
100
|
+
["unzip", ["-o", "-q", tmp, "-d", dest]],
|
|
101
|
+
];
|
|
102
|
+
let extracted = false;
|
|
103
|
+
for (const [cmd, cargs] of extractors) {
|
|
104
|
+
try {
|
|
105
|
+
execFileSync(cmd, cargs, { stdio: ["ignore", "ignore", "ignore"] });
|
|
106
|
+
extracted = true;
|
|
107
|
+
break;
|
|
108
|
+
} catch {
|
|
109
|
+
// 尝试下一个解压器
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (!extracted) {
|
|
113
|
+
console.error(`解压失败(需系统 tar 或 unzip 命令)。安装包已存到: ${tmp}`);
|
|
114
|
+
console.error(`可手动解压: tar -xf "${tmp}" -C "${dest}"`);
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
rmSync(tmp, { force: true });
|
|
118
|
+
|
|
119
|
+
// 注入 API Key:有 .env.example 按模板替换占位,否则直接写最小 .env;已有 .env 不覆盖。
|
|
120
|
+
const envPath = join(dest, ".env");
|
|
121
|
+
if (!existsSync(envPath)) {
|
|
122
|
+
let envBody = `MANTURHUB_KEY=${key}\n`;
|
|
123
|
+
const examplePath = join(dest, ".env.example");
|
|
124
|
+
if (existsSync(examplePath)) {
|
|
125
|
+
envBody = readFileSync(examplePath, "utf8")
|
|
126
|
+
.replace(/^(MANTURHUB_KEY\s*=).*$/m, `$1${key}`);
|
|
127
|
+
if (!/MANTURHUB_KEY/.test(envBody)) envBody += `\nMANTURHUB_KEY=${key}\n`;
|
|
128
|
+
}
|
|
129
|
+
writeFileSync(envPath, envBody, { mode: 0o600 });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
console.log(`✓ 已安装套件「${slug}」→ ${dest}`);
|
|
133
|
+
console.log(` API Key 已写入 ${join(dest, ".env")}`);
|
|
134
|
+
console.log(`\n下一步:用你的 Agent(Claude Code / Codex / Cursor…)打开该目录,直接说需求即可开工:`);
|
|
135
|
+
console.log(` cd ${dest}`);
|
|
136
|
+
}
|