museav-cli 2.10.2 → 3.0.1

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/AGENTS.md CHANGED
@@ -6,6 +6,24 @@ This CLI is designed to be used directly by coding agents (Claude Code, Codex, e
6
6
 
7
7
  A command-line client for the "studio" image-generation platform (`https://manager.museav.top`). It generates images from a prompt, reverse-engineers a prompt from an existing image, and lists your own generation history. All output is designed for machine consumption: **stdout carries only the final result** (a URL, a prompt string, or JSON); progress and human-readable info goes to stderr.
8
8
 
9
+ ## Scope: this tool makes *assets*, not finished videos
10
+
11
+ Know the boundary before you pick a tool:
12
+
13
+ | You need | Use |
14
+ |---|---|
15
+ | An image, or a raw video clip from a model | `museav gen` (add `--video`) |
16
+ | Cut out a background / upscale / de-watermark / compress | `museav remove-bg` / `upscale` / `remove-watermark` / `compress` |
17
+ | **A finished vertical short video** (images + per-shot captions + BGM/voiceover, templated) | **[reel-kit](https://github.com/webkubor/reel-kit)** — `reel make` |
18
+
19
+ `museav gen --video` gives you a **silent, caption-less clip** — that's raw material, not
20
+ something you post. Assembling material into a publishable short is reel-kit's job: its
21
+ layouts are HTML/CSS templates, it does voiceover, and **shot length follows the narration**.
22
+
23
+ > `museav slideshow` existed in 2.9–2.10 and was **retired in 3.0.0** — it duplicated
24
+ > reel-kit. The command still exists as a stub that prints migration instructions.
25
+ > Don't try to bring it back; use reel-kit.
26
+
9
27
  ## Auth: pick one identity, not both
10
28
 
11
29
  - **You're acting as an individual user** (a person's own account): `museav login` — opens a device-authorization flow (prints a code + URL, polls until the user approves in a browser). Token cached in `~/.museav.json`, valid 7 days.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,65 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.0.1 (2026-08-28)
4
+
5
+ ### 把 reel-kit 的推荐位做实
6
+
7
+ 3.0.0 只是下线了 slideshow,但没告诉人「那该用什么」——README 里只有一句藏在引用块里的
8
+ 说明,agent 读的 AGENTS.md 里一个字都没提。补三处:
9
+
10
+ - **README** 加独立小节「🎬 要出成品视频?用 reel-kit」,带命令示例与分工对照表
11
+ - **AGENTS.md** 加 "Scope: this tool makes *assets*, not finished videos" ——
12
+ agent 被要求「做个视频」时,第一眼就能看到该去哪
13
+ - **`gen --video` 出片后提示一行**:模型出的是无声无字幕素材,不是成品。
14
+ 这不是广告,是防止两种误解——以为「出完了」,或以为 museav 该管配音烧字幕
15
+
16
+ 典型链路写清楚了:`museav gen` 出图 → `museav remove-bg` 抠图 → `reel make` 出片。
17
+
18
+ ## 3.0.0 (2026-08-28)
19
+
20
+ ### 破坏性变更:`slideshow` / `slideshow-layouts` 下线,出片改用 reel-kit
21
+
22
+ 2.9.0 在这里做了「图集转竖版短视频」。**当天就发现
23
+ [reel-kit](https://github.com/webkubor/reel-kit) 早已做了同一件事,而且更好**:
24
+
25
+ | | reel-kit | museav slideshow(已下线) |
26
+ |---|---|---|
27
+ | 排版 | HTML/CSS —— 文字换行、阴影、渐变都免费 | SVG,**不支持文字换行** |
28
+ | 加版式 | 往 `templates/` 丢一个 HTML | 手写图层 DSL |
29
+ | 配音 | 有,且**镜头时长由念白长度决定** | 无 |
30
+ | TTS 成本 | 本地 voxcraft,一次性模型、之后免费 | — |
31
+
32
+ 所以能力收敛到 reel-kit 一处:
33
+
34
+ ```bash
35
+ reel make --template sticker-promo \
36
+ --assets ./图片目录 --caps 文案.txt \
37
+ --title "标题" --bgm 儿童轻快 --out 成片.mp4
38
+ ```
39
+
40
+ 装:`cd <reel-kit 检出> && pnpm install && npm link`(需 ffmpeg + Chrome)。
41
+ 找不到检出位置就 `cs repo reel-kit`。
42
+
43
+ **命令留了存根**而不是直接删:已发布过 2.9~2.10,脚本里可能写着 `museav slideshow`,
44
+ 直接删只会得到一句 `unknown command`。现在跑它会打印迁移说明并以退出码 1 结束,
45
+ 老参数(`--title` / `--layout` 等)也不会导致解析报错。下个大版本移除存根。
46
+
47
+ 一并移除:`src/local-slideshow.ts`、`src/slideshow-presets.ts`、`src/commands/slideshow.ts`,
48
+ 以及 `StudioClient` 上的 `slideshowLayouts` / `slideshowLayout` / `createSlideshowLayout`
49
+ (`client.ts` 是包的公开导出,留没人调的方法会让人以为还能用)。
50
+
51
+ 中台的 `/api/slideshow-layouts` 与 `slideshow_layouts` 表**没有删**(删表不可逆),
52
+ 但当前没有消费者。若将来要给 reel-kit 做「模板跨机器共享」,那张表可以改存 HTML 模板复用。
53
+
54
+ ### museav 的边界因此更清楚了
55
+
56
+ **museav 管素材**:`remove-bg` 抠图、`upscale` 超分、`remove-watermark` 去水印、
57
+ `compress` 压缩、`gen` 生成图/视频素材。
58
+ **reel-kit 管成品合成**:套版式、配文案、配乐、配音、烧字幕。
59
+
60
+ reel-kit 那边早就明写了这条边界(「本工具不做抠图 —— 那是 museav remove-bg 的职责,
61
+ 在这里重做一遍只会变成第二套实现」),是这边越了界。教训:动手前先 `cs repo <关键词>` 搜一遍。
62
+
3
63
  ## 2.10.2 (2026-08-28)
4
64
 
5
65
  ### 修复:排版模板的图层顺序失效,图片会盖住它下面该有的文字
package/README.md CHANGED
@@ -102,16 +102,44 @@
102
102
  | | 抠图去背景(输出透明 PNG) | `remove-bg` |
103
103
  | | **放大清晰度**(2M → 10M+ 级) | `upscale` |
104
104
  | | 去水印 | `remove-watermark` |
105
- | | **一组图 → 竖版短视频**(带标题/文案/配乐) | `slideshow` |
106
105
  | **语音**(直连小米 MiMo,需 `MIMO_API_KEY`) | 文字转语音 / 音色设计 / 音色克隆 | `speak` |
107
106
  | | 语音转文字 | `transcribe` |
108
107
  | **素材与统计** | 上传素材 / 查任务 / 查余额 / 查模型 / 查身份 | `upload` / `jobs` / `balance` / `models` / `whoami` |
109
108
 
110
- > 本地工具(`compress` / `remove-bg` / `upscale` / `remove-watermark` / `slideshow`)**不用登录、不花一分钱**,装了就能用;其余命令需要一个凭证(个人 `login` 或租户 apiKey)。
109
+ > 本地工具(`compress` / `remove-bg` / `upscale` / `remove-watermark`)**不用登录、不花一分钱**,装了就能用;其余命令需要一个凭证(个人 `login` 或租户 apiKey)。
111
110
  >
112
111
  > 语音(`speak` / `transcribe`)是第三种情况:**不走中台身份**,直连小米 MiMo,只认 `MIMO_API_KEY` 环境变量。
113
112
  > 中台的出音链路还没接完,这批能力目前内部用,没有那把 key 的人(包括租户)用不了。
114
113
 
114
+ ### 🎬 要出成品视频?用 [reel-kit](https://github.com/webkubor/reel-kit)
115
+
116
+ museav 出的是**素材**:`gen --video` 给你的是一段**无声、无字幕的片子**,
117
+ 那是原料,不是能直接发的成品。把素材装配成能发的竖版短片是
118
+ **[reel-kit](https://github.com/webkubor/reel-kit)** 的活:
119
+
120
+ ```bash
121
+ reel make --template sticker-promo \
122
+ --assets ./图片目录 --caps 文案.txt \
123
+ --title "标题" --bgm 儿童轻快 --out 成片.mp4
124
+ ```
125
+
126
+ - 版式是 `templates/*.html`,**改 CSS 就是改版式**,丢一个 HTML 进去就是一个新模板
127
+ - 支持配音,且**镜头时长跟着念白走**(念快的不干等,念慢的不被切)
128
+ - 配音默认走本地 TTS,批量出片不花钱
129
+
130
+ 两边的分工是明确的,reel-kit 也在它的 README 里写了同一条边界:
131
+
132
+ | 你要的 | 用谁 |
133
+ |---|---|
134
+ | 一张图 / 一段模型出的原始片子 | `museav gen`(加 `--video`) |
135
+ | 抠图 / 超分 / 去水印 / 压缩 | `museav remove-bg` / `upscale` / `remove-watermark` / `compress` |
136
+ | **一支能直接发的竖版短片** | **`reel make`** |
137
+
138
+ 典型链路:`museav gen` 出图 → `museav remove-bg` 抠图 → `reel make` 出片。
139
+
140
+ > `museav slideshow` 在 2.9~2.10 存在过,**3.0.0 已下线** —— 它和 reel-kit 重复了。
141
+ > 命令还在但只会打印迁移说明。详见 [CHANGELOG](./CHANGELOG.md)。
142
+
115
143
  ---
116
144
 
117
145
  ## 快速开始
@@ -441,66 +469,16 @@ museav remove-watermark photo.jpg --mask mask.png # 复杂画面手工掩
441
469
  - 依赖红线:本地**绝不自动拉起开源大模型**——这些工具是轻量 CNN/传统算法,用完即释放内存。reverse 的本地路已翻回显式 `--local`(需自备 Ollama),默认走中台 API。
442
470
  - 二进制与模型缓存:`~/.museav-bin/upscayl`(引擎)、`~/.museav-models/`(模型),Windows 对应 `%USERPROFILE%` 下同名目录;删除即彻底清理。
443
471
 
444
- ### 图集转竖版短视频 `slideshow`(免登录)
445
-
446
- 一组图 + 每张的文案 + 一段配乐 → 一条能直接发朋友圈 / 视频号 / 小红书的竖版视频。
447
- 排版走 sharp + SVG(中文用系统字体),合成走 ffmpeg,**需要本机装了 ffmpeg**(`brew install ffmpeg`)。
448
-
449
- ```bash
450
- # 最简:一个目录里的图,按文件名排序串成视频
451
- museav slideshow ./图片目录 --out 成片.mp4
452
-
453
- # 完整:标题 + 逐张文案 + 配乐
454
- museav slideshow ./表情图 \
455
- --title "莓啾日常" --subtitle "莓啾 · 微信表情包" \
456
- --caption "需要被安慰的时候" --caption "催外卖 / 催开饭" \
457
- --footer "微信搜「莓啾日常」添加整套" \
458
- --music bgm.mp3 --sec 2.2 --out 推广视频.mp4
459
-
460
- # 文案多的时候写文件里,每行一条
461
- museav slideshow ./图片目录 --captions 文案.txt --title "作品集"
462
- ```
463
-
464
- 默认 1080×1920 / 30fps / H.264+AAC,每张停 2.5 秒;`--size` 换尺寸、`--theme dark` 换深色底。
465
-
466
- #### 排版模板:版面不写死在代码里
472
+ ### 出成品视频:走 reel-kit
467
473
 
468
- 版面由一份**图层 DSL** 描述,模板库在中台,改版式不用等 CLI 发新版:
474
+ 不在本 CLI,见上面 [🎬 要出成品视频](#-要出成品视频用-reel-kit)。常用三条:
469
475
 
470
476
  ```bash
471
- museav slideshow-layouts # 看有哪些版式(内置 + 中台)
472
- museav slideshow ./图 --layout <slug> # 用中台模板
473
- museav slideshow ./图 --layout-file my.json # 用本地 JSON(调模板时用,免登录)
474
- museav slideshow-layouts create my.json --name 我的版式 --slug my-style
477
+ reel make --template sticker-promo --assets ./图 --caps 文案.txt --out 成片.mp4
478
+ reel templates # 看版式
479
+ reel bgm # 看配乐库(带授权)
475
480
  ```
476
481
 
477
- DSL 支持 `rect` / `ellipse` / `text` / `slot` / `image` 五种图层。`text` 和 `slot` 用 `bind`
478
- 绑定内容(`title` / `subtitle` / `caption` / `footer` / `image`),所以同一个模板能套任意一套素材;
479
- `image` 层可以写 `sticker://<id>` 引用中台贴图库里的透明装饰图。
480
-
481
- ```json
482
- {
483
- "canvas": { "w": 1080, "h": 1920, "bg": "#ffffff" },
484
- "layers": [
485
- { "type": "ellipse", "cx": 190, "cy": -131, "rx": 510, "ry": 430, "fill": "#ffd6e2" },
486
- { "type": "text", "bind": "title", "x": 540, "y": 394, "size": 84, "align": "center", "maxWidth": 0.86 },
487
- { "type": "slot", "bind": "image", "box": [281, 660, 518, 701], "fit": "contain", "trim": true }
488
- ]
489
- }
490
- ```
491
-
492
- > **不给 `--layout` 就完全不碰网络**,用内置版式出片。免登录是这个命令的立身之本,接了模板库也没丢。
493
- >
494
- > 模板结构的真源与校验都在中台。CLI 是消费方,遇到不认识的图层类型**跳过该层并提示升级**,
495
- > 不报错中断 —— 老 CLI 碰上新层类型该少画一层,不是彻底出不了片。
496
-
497
- 三个不写出来就会踩的点,已经在实现里处理掉了:
498
-
499
- - **小图会被显式放大**。240×240 的贴纸直接贴到 1080 宽的画布上只占两成宽,画面空得离谱。
500
- 贴纸类图片还会先裁掉四周透明留白再放大(`--no-trim` 关掉),否则放大的是留白不是主体。
501
- - **配乐不会中途硬切断**。配乐通常比视频长几倍,直接 `-shortest` 会在句子中间断掉;
502
- 这里裁到视频时长并做首尾淡入淡出。
503
- - **末页不会一闪而过**。ffmpeg 的 concat demuxer 会忽略最后一项的 duration,实现里把末页多列了一次。
504
482
 
505
483
  ### 项目(工作区)与项目素材库 `projects`
506
484
 
@@ -626,9 +604,7 @@ console.log(r.sculpt.light) // 光影分析
626
604
  | `remove-bg <file>` | 本地抠图去背景(免登录,输出带 alpha 的 PNG) | 产物路径 |
627
605
  | `upscale <file>` | 本地超分放大,2M 图变 10M+(免登录,Real-ESRGAN GPU,`--scale 2/3/4`) | 产物路径 |
628
606
  | `remove-watermark <file>` | 本地去水印(免登录,自动定位 + LaMa 修复,`--mask` 手工兜底) | 产物路径 |
629
- | `slideshow <图片或目录...>` | 图集转竖版短视频(免登录,带标题/逐张文案/配乐,需 ffmpeg) | 产物路径 |
630
- | `slideshow-layouts` | 查排版模板:内置版式(免登录)+ 中台模板(平台/租户/私有) | slug 列表 |
631
- | `slideshow-layouts create <json>` | 从 JSON 新建排版模板(结构校验在服务端做) | 新模板 id |
607
+ | `slideshow` / `slideshow-layouts` | **已下线(3.0.0)**,出片走 reel-kit;跑一下会打印迁移说明 | 迁移指引 |
632
608
  | `projects` | 工作区(项目)列表:一账户多项目,各带自己的素材库 | 项目 id 列表 |
633
609
  | `projects assets --project` | 项目素材库:ls / add / rm(垫图母版,人像库/产品库各管各的) | `id<TAB>url` 行 |
634
610
  | `models` | 可用模型 | 模型名列表 |
package/dist/client.d.ts CHANGED
@@ -343,20 +343,6 @@ export declare class StudioClient {
343
343
  createSticker(filePath: string, name: string): Promise<any>;
344
344
  /** 删除贴图素材 */
345
345
  deleteSticker(id: string): Promise<void>;
346
- /** 排版模板清单(图集视频用):平台共享 + 本租户 + 本人私有,服务端按身份过滤 */
347
- slideshowLayouts(): Promise<any[]>;
348
- /** 按 slug 取单个排版模板(CLI 的 --layout 走这条) */
349
- slideshowLayout(slug: string): Promise<any>;
350
- /** 新建排版模板。layout 的结构校验在服务端做,这里不预校验——
351
- * 两侧都校验的话,老 CLI 会把新写的合法模板判为非法。 */
352
- createSlideshowLayout(input: {
353
- name: string;
354
- slug: string;
355
- layout: unknown;
356
- description?: string;
357
- category?: string;
358
- sample_url?: string;
359
- }): Promise<any>;
360
346
  /** 版式模板清单(租户级资产):封面底图 + 固定描述({城市}{明星} 占位符) */
361
347
  posterTemplates(): Promise<any[]>;
362
348
  /** 上传版式模板(不压缩,保留封面底图原样) */
package/dist/client.js CHANGED
@@ -142,25 +142,11 @@ export class StudioClient {
142
142
  async deleteSticker(id) {
143
143
  await this.request(`stickers?id=${encodeURIComponent(id)}`, { method: 'DELETE' });
144
144
  }
145
- /** 排版模板清单(图集视频用):平台共享 + 本租户 + 本人私有,服务端按身份过滤 */
146
- async slideshowLayouts() {
147
- const r = await this.request('slideshow-layouts');
148
- return Array.isArray(r) ? r : [];
149
- }
150
- /** 按 slug 取单个排版模板(CLI 的 --layout 走这条) */
151
- async slideshowLayout(slug) {
152
- return this.request(`slideshow-layouts?slug=${encodeURIComponent(slug)}`);
153
- }
154
- /** 新建排版模板。layout 的结构校验在服务端做,这里不预校验——
155
- * 两侧都校验的话,老 CLI 会把新写的合法模板判为非法。 */
156
- async createSlideshowLayout(input) {
157
- const r = await this.request('slideshow-layouts', {
158
- method: 'POST',
159
- headers: { 'Content-Type': 'application/json' },
160
- body: JSON.stringify(input),
161
- });
162
- return r.layout ?? r;
163
- }
145
+ // slideshowLayouts / slideshowLayout / createSlideshowLayout 已随 slideshow 命令下线(3.0.0)。
146
+ // 中台的 /api/slideshow-layouts 与 slideshow_layouts 表仍在(没删表,那是不可逆操作),
147
+ // 但当前没有消费者 —— 出片走 reel-kit,它的版式是本地 HTML 模板。
148
+ // 若将来要给 reel-kit 做「模板跨机器共享」,那张表可以改存 HTML 模板复用,
149
+ // 到时再按需要的形状重写客户端方法,而不是留一份没人调的死代码在公开导出里。
164
150
  /** 版式模板清单(租户级资产):封面底图 + 固定描述({城市}{明星} 占位符) */
165
151
  async posterTemplates() {
166
152
  const r = await this.request('poster-templates');
@@ -88,6 +88,12 @@ export async function gen(client, opts) {
88
88
  throw new Error(`视频生成失败: ${result.error || '未知原因'}`);
89
89
  }
90
90
  process.stderr.write(`✅ 视频完成\n`);
91
+ // 模型出的是**无声、无字幕的素材**,不是能直接发的成品。这一行是为了让人在拿到
92
+ // URL 的那一刻就知道下一步去哪 —— 而不是以为「出完了」,或者反过来以为
93
+ // museav 该管配音烧字幕(那是 reel-kit 的活,两边边界见 AGENTS.md)。
94
+ // 只在视频模式提示,且走 stderr 不污染 stdout。
95
+ process.stderr.write(` 这是无声无字幕的素材。要装配成能发的成品(配文案/配乐/配音):\n` +
96
+ ` reel make --assets <图目录> --caps 文案.txt → github.com/webkubor/reel-kit\n`);
91
97
  console.log(result.cdn_url);
92
98
  return;
93
99
  }
package/dist/index.js CHANGED
@@ -16,7 +16,6 @@ import { printWelcome } from './commands/welcome.js';
16
16
  import { gen } from './commands/gen.js';
17
17
  import { reverse } from './commands/reverse.js';
18
18
  import { compressCmd, removeBgCmd, upscaleCmd, removeWatermarkCmd } from './commands/img-tools.js';
19
- import { slideshowCmd, slideshowLayoutsCmd, createSlideshowLayoutCmd } from './commands/slideshow.js';
20
19
  import { projects, createProject, listAssets, addAsset, removeAsset } from './commands/projects.js';
21
20
  import { imageToTemplate } from './commands/image-to-template.js';
22
21
  import { upload } from './commands/upload.js';
@@ -204,34 +203,42 @@ program
204
203
  .option('--mask <file>', '手工掩码图(白色=要去除的区域),跳过自动定位')
205
204
  .option('--overwrite', '允许覆盖已存在的输出文件')
206
205
  .action(asyncRun((input, opts) => removeWatermarkCmd(input, opts)));
207
- program
208
- .command('slideshow <图片或目录...>')
209
- .description('本地图集转竖版短视频(sharp + ffmpeg,免登录):默认 1080×1920 / 30fps / H.264,可加标题、逐张文案与配乐。需要本机有 ffmpeg')
210
- .option('--out <path>', '输出 mp4(默认当前目录 slideshow.mp4)')
211
- .option('--title <text>', '顶部主标题(大字)')
212
- .option('--subtitle <text>', '顶部副标题(小字)')
213
- .option('--caption <text>', '单页文案,可重复传,按顺序对应每张图', (v, acc) => [...acc, v], [])
214
- .option('--captions <file>', '文案文件(每行一条,按顺序对应每张图),与 --caption 二选一')
215
- .option('--footer <text>', '底部引导语')
216
- .option('--music <file>', '配乐音频。自动裁到视频长度并加首尾淡入淡出(不会中途硬切断)')
217
- .option('--sec <n>', '每张停留秒数,默认取模板的(内置模板 2.5)')
218
- .option('--size <WxH>', '画面尺寸,默认取模板画布(内置模板 1080x1920);与模板不同则整体等比缩放')
219
- .option('--theme <name>', 'light(默认)/ dark。只影响内置版式,给了 --layout 就以模板为准')
220
- .option('--layout <slug>', '排版模板 slug:内置的直接用,其余去中台拉(需登录)。清单见 museav slideshow-layouts')
221
- .option('--layout-file <path>', '直接用本地 JSON 排版模板(调模板时用,免登录)')
222
- .action(asyncRun((paths, opts) => slideshowCmd(paths, opts)));
223
- const slideshowLayoutsCommand = program
224
- .command('slideshow-layouts')
225
- .description('查排版模板:内置版式(免登录)+ 中台模板(平台共享 / 本租户 / 本人私有)。配合 slideshow --layout 使用')
226
- .action(asyncRun(() => slideshowLayoutsCmd()));
227
- slideshowLayoutsCommand
228
- .command('create <layout.json>')
229
- .description('从 JSON 文件新建排版模板——归属由身份自动决定:租户 Key 建的归本租户,个人账号建的仅本人可见。结构校验在服务端做')
230
- .requiredOption('--name <名称>', '模板中文名')
231
- .requiredOption('--slug <slug>', '对外调用标识(小写字母/数字/连字符,全局唯一)')
232
- .option('--description <text>', '模板说明')
233
- .option('--category <name>', '分类,默认「其他」')
234
- .action(asyncRun((file, opts) => createSlideshowLayoutCmd(file, opts)));
206
+ /**
207
+ * slideshow / slideshow-layouts —— 已下线(3.0.0),转向 reel-kit。
208
+ *
209
+ * 2.9.0 在这里做了「图集转竖版短视频」,当天就发现 reel-kit
210
+ * (github.com/webkubor/reel-kit)早已做了同一件事,而且更好:
211
+ * 版式走 HTML/CSS(文字能换行、能做阴影渐变,这里的 SVG 方案做不到)、
212
+ * 支持配音且镜头时长由念白长度决定、默认本地 TTS 零成本、
213
+ * 加版式只需往 templates/ 丢一个 HTML。
214
+ *
215
+ * 所以能力收敛到 reel-kit 一处,这边下线。**留存根而不是直接删命令**:
216
+ * 已发布过 2.9~2.10,脚本里可能写着 museav slideshow,
217
+ * 直接删会得到一句 "unknown command" 而不知道该去哪 —— 存根负责把人送到对岸。
218
+ * 下个大版本再移除。
219
+ *
220
+ * museav 的边界因此回到:素材处理(compress/remove-bg/upscale/remove-watermark)
221
+ * + AI 生成(gen)+ 中台资产。成品合成不在这里。
222
+ */
223
+ const RETIRED_HINT = (cmd) => (`museav ${cmd} 已下线(3.0.0),出片能力收敛到 reel-kit:\n\n` +
224
+ ` reel make --template sticker-promo \\\n` +
225
+ ` --assets ./图片目录 --caps 文案.txt \\\n` +
226
+ ` --title "标题" --bgm 儿童轻快 --out 成片.mp4\n\n` +
227
+ `装: cd <reel-kit 检出目录> && pnpm install && npm link (需 ffmpeg + Chrome)\n` +
228
+ `找: cs repo reel-kit\n` +
229
+ `看版式: reel templates 看配乐: reel bgm\n\n` +
230
+ `为什么换:reel-kit 的版式走 HTML/CSS(文字能换行、能做阴影渐变),\n` +
231
+ `还支持配音且镜头时长由念白决定,本地 TTS 零成本。同一件事没必要两套实现。`);
232
+ for (const [name, args] of [['slideshow', ' [图片或目录...]'], ['slideshow-layouts', '']]) {
233
+ program
234
+ .command(`${name}${args}`)
235
+ .description(`(已下线,改用 reel-kit 的 reel make —— 跑一下看迁移说明)`)
236
+ .allowUnknownOption() // 老命令行里带着 --title/--layout 等参数,也要能跑到提示这一步
237
+ .action(() => {
238
+ process.stderr.write(`\n${RETIRED_HINT(name)}\n`);
239
+ process.exit(1);
240
+ });
241
+ }
235
242
  // 工作区(项目)与项目素材库:平台 → 账户 → 工作区三层归属,素材挂工作区
236
243
  const projectsCmd = program
237
244
  .command('projects')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "museav-cli",
3
- "version": "2.10.2",
3
+ "version": "3.0.1",
4
4
  "description": "MUSE AV 出图中台官方 CLI —— 命令行调中台 API 出图、出视频、读图逆向、图生模板",
5
5
  "type": "module",
6
6
  "bin": {
package/src/client.ts CHANGED
@@ -452,30 +452,11 @@ export class StudioClient {
452
452
  await this.request(`stickers?id=${encodeURIComponent(id)}`, { method: 'DELETE' })
453
453
  }
454
454
 
455
- /** 排版模板清单(图集视频用):平台共享 + 本租户 + 本人私有,服务端按身份过滤 */
456
- async slideshowLayouts(): Promise<any[]> {
457
- const r = await this.request('slideshow-layouts')
458
- return Array.isArray(r) ? r : []
459
- }
460
-
461
- /** 按 slug 取单个排版模板(CLI 的 --layout 走这条) */
462
- async slideshowLayout(slug: string): Promise<any> {
463
- return this.request(`slideshow-layouts?slug=${encodeURIComponent(slug)}`)
464
- }
465
-
466
- /** 新建排版模板。layout 的结构校验在服务端做,这里不预校验——
467
- * 两侧都校验的话,老 CLI 会把新写的合法模板判为非法。 */
468
- async createSlideshowLayout(input: {
469
- name: string; slug: string; layout: unknown
470
- description?: string; category?: string; sample_url?: string
471
- }): Promise<any> {
472
- const r = await this.request('slideshow-layouts', {
473
- method: 'POST',
474
- headers: { 'Content-Type': 'application/json' },
475
- body: JSON.stringify(input),
476
- })
477
- return r.layout ?? r
478
- }
455
+ // slideshowLayouts / slideshowLayout / createSlideshowLayout 已随 slideshow 命令下线(3.0.0)。
456
+ // 中台的 /api/slideshow-layouts 与 slideshow_layouts 表仍在(没删表,那是不可逆操作),
457
+ // 但当前没有消费者 —— 出片走 reel-kit,它的版式是本地 HTML 模板。
458
+ // 若将来要给 reel-kit 做「模板跨机器共享」,那张表可以改存 HTML 模板复用,
459
+ // 到时再按需要的形状重写客户端方法,而不是留一份没人调的死代码在公开导出里。
479
460
 
480
461
  /** 版式模板清单(租户级资产):封面底图 + 固定描述({城市}{明星} 占位符) */
481
462
  async posterTemplates(): Promise<any[]> {
@@ -109,6 +109,14 @@ export async function gen(client: StudioClient, opts: {
109
109
  throw new Error(`视频生成失败: ${result.error || '未知原因'}`)
110
110
  }
111
111
  process.stderr.write(`✅ 视频完成\n`)
112
+ // 模型出的是**无声、无字幕的素材**,不是能直接发的成品。这一行是为了让人在拿到
113
+ // URL 的那一刻就知道下一步去哪 —— 而不是以为「出完了」,或者反过来以为
114
+ // museav 该管配音烧字幕(那是 reel-kit 的活,两边边界见 AGENTS.md)。
115
+ // 只在视频模式提示,且走 stderr 不污染 stdout。
116
+ process.stderr.write(
117
+ ` 这是无声无字幕的素材。要装配成能发的成品(配文案/配乐/配音):\n` +
118
+ ` reel make --assets <图目录> --caps 文案.txt → github.com/webkubor/reel-kit\n`,
119
+ )
112
120
  console.log(result.cdn_url)
113
121
  return
114
122
  }
package/src/index.ts CHANGED
@@ -16,7 +16,6 @@ import { printWelcome } from './commands/welcome.js'
16
16
  import { gen } from './commands/gen.js'
17
17
  import { reverse } from './commands/reverse.js'
18
18
  import { compressCmd, removeBgCmd, upscaleCmd, removeWatermarkCmd } from './commands/img-tools.js'
19
- import { slideshowCmd, slideshowLayoutsCmd, createSlideshowLayoutCmd } from './commands/slideshow.js'
20
19
  import { projects, createProject, listAssets, addAsset, removeAsset, resolveWorkspace } from './commands/projects.js'
21
20
  import { imageToTemplate } from './commands/image-to-template.js'
22
21
  import { upload } from './commands/upload.js'
@@ -212,36 +211,45 @@ program
212
211
  .option('--overwrite', '允许覆盖已存在的输出文件')
213
212
  .action(asyncRun((input: string, opts: any) => removeWatermarkCmd(input, opts)))
214
213
 
215
- program
216
- .command('slideshow <图片或目录...>')
217
- .description('本地图集转竖版短视频(sharp + ffmpeg,免登录):默认 1080×1920 / 30fps / H.264,可加标题、逐张文案与配乐。需要本机有 ffmpeg')
218
- .option('--out <path>', '输出 mp4(默认当前目录 slideshow.mp4)')
219
- .option('--title <text>', '顶部主标题(大字)')
220
- .option('--subtitle <text>', '顶部副标题(小字)')
221
- .option('--caption <text>', '单页文案,可重复传,按顺序对应每张图', (v: string, acc: string[]) => [...acc, v], [] as string[])
222
- .option('--captions <file>', '文案文件(每行一条,按顺序对应每张图),与 --caption 二选一')
223
- .option('--footer <text>', '底部引导语')
224
- .option('--music <file>', '配乐音频。自动裁到视频长度并加首尾淡入淡出(不会中途硬切断)')
225
- .option('--sec <n>', '每张停留秒数,默认取模板的(内置模板 2.5)')
226
- .option('--size <WxH>', '画面尺寸,默认取模板画布(内置模板 1080x1920);与模板不同则整体等比缩放')
227
- .option('--theme <name>', 'light(默认)/ dark。只影响内置版式,给了 --layout 就以模板为准')
228
- .option('--layout <slug>', '排版模板 slug:内置的直接用,其余去中台拉(需登录)。清单见 museav slideshow-layouts')
229
- .option('--layout-file <path>', '直接用本地 JSON 排版模板(调模板时用,免登录)')
230
- .action(asyncRun((paths: string[], opts: any) => slideshowCmd(paths, opts)))
231
-
232
- const slideshowLayoutsCommand = program
233
- .command('slideshow-layouts')
234
- .description('查排版模板:内置版式(免登录)+ 中台模板(平台共享 / 本租户 / 本人私有)。配合 slideshow --layout 使用')
235
- .action(asyncRun(() => slideshowLayoutsCmd()))
236
-
237
- slideshowLayoutsCommand
238
- .command('create <layout.json>')
239
- .description('从 JSON 文件新建排版模板——归属由身份自动决定:租户 Key 建的归本租户,个人账号建的仅本人可见。结构校验在服务端做')
240
- .requiredOption('--name <名称>', '模板中文名')
241
- .requiredOption('--slug <slug>', '对外调用标识(小写字母/数字/连字符,全局唯一)')
242
- .option('--description <text>', '模板说明')
243
- .option('--category <name>', '分类,默认「其他」')
244
- .action(asyncRun((file: string, opts: any) => createSlideshowLayoutCmd(file, opts)))
214
+ /**
215
+ * slideshow / slideshow-layouts —— 已下线(3.0.0),转向 reel-kit。
216
+ *
217
+ * 2.9.0 在这里做了「图集转竖版短视频」,当天就发现 reel-kit
218
+ * (github.com/webkubor/reel-kit)早已做了同一件事,而且更好:
219
+ * 版式走 HTML/CSS(文字能换行、能做阴影渐变,这里的 SVG 方案做不到)、
220
+ * 支持配音且镜头时长由念白长度决定、默认本地 TTS 零成本、
221
+ * 加版式只需往 templates/ 丢一个 HTML。
222
+ *
223
+ * 所以能力收敛到 reel-kit 一处,这边下线。**留存根而不是直接删命令**:
224
+ * 已发布过 2.9~2.10,脚本里可能写着 museav slideshow,
225
+ * 直接删会得到一句 "unknown command" 而不知道该去哪 —— 存根负责把人送到对岸。
226
+ * 下个大版本再移除。
227
+ *
228
+ * museav 的边界因此回到:素材处理(compress/remove-bg/upscale/remove-watermark)
229
+ * + AI 生成(gen)+ 中台资产。成品合成不在这里。
230
+ */
231
+ const RETIRED_HINT = (cmd: string) => (
232
+ `museav ${cmd} 已下线(3.0.0),出片能力收敛到 reel-kit:\n\n` +
233
+ ` reel make --template sticker-promo \\\n` +
234
+ ` --assets ./图片目录 --caps 文案.txt \\\n` +
235
+ ` --title "标题" --bgm 儿童轻快 --out 成片.mp4\n\n` +
236
+ `装: cd <reel-kit 检出目录> && pnpm install && npm link (需 ffmpeg + Chrome)\n` +
237
+ `找: cs repo reel-kit\n` +
238
+ `看版式: reel templates 看配乐: reel bgm\n\n` +
239
+ `为什么换:reel-kit 的版式走 HTML/CSS(文字能换行、能做阴影渐变),\n` +
240
+ `还支持配音且镜头时长由念白决定,本地 TTS 零成本。同一件事没必要两套实现。`
241
+ )
242
+
243
+ for (const [name, args] of [['slideshow', ' [图片或目录...]'], ['slideshow-layouts', '']] as const) {
244
+ program
245
+ .command(`${name}${args}`)
246
+ .description(`(已下线,改用 reel-kit 的 reel make —— 跑一下看迁移说明)`)
247
+ .allowUnknownOption() // 老命令行里带着 --title/--layout 等参数,也要能跑到提示这一步
248
+ .action(() => {
249
+ process.stderr.write(`\n${RETIRED_HINT(name)}\n`)
250
+ process.exit(1)
251
+ })
252
+ }
245
253
 
246
254
  // 工作区(项目)与项目素材库:平台 → 账户 → 工作区三层归属,素材挂工作区
247
255
  const projectsCmd = program
@@ -1,24 +0,0 @@
1
- export interface SlideshowCmdOpts {
2
- out?: string;
3
- title?: string;
4
- subtitle?: string;
5
- footer?: string;
6
- caption?: string[];
7
- captions?: string;
8
- music?: string;
9
- sec?: string;
10
- size?: string;
11
- theme?: string;
12
- layout?: string;
13
- layoutFile?: string;
14
- }
15
- export declare function slideshowCmd(paths: string[], opts: SlideshowCmdOpts): Promise<void>;
16
- /** museav slideshow-layouts —— 列出可用排版模板(内置 + 中台) */
17
- export declare function slideshowLayoutsCmd(): Promise<void>;
18
- /** museav slideshow-layouts create —— 从 JSON 文件建一个排版模板 */
19
- export declare function createSlideshowLayoutCmd(file: string, opts: {
20
- name: string;
21
- slug: string;
22
- description?: string;
23
- category?: string;
24
- }): Promise<void>;