@optima-chat/gen-cli 1.0.9 → 1.1.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.
Files changed (37) hide show
  1. package/.claude/skills/gen/SKILL.md +345 -0
  2. package/.claude/skills/multigrid-poster/SKILL.md +194 -0
  3. package/.claude/skills/multigrid-poster/layouts/2x2.json +34 -0
  4. package/.claude/skills/multigrid-poster/layouts/3x3.json +43 -0
  5. package/.claude/skills/multigrid-poster/scripts/compose.py +116 -0
  6. package/.claude/skills/multigrid-poster/scripts/placeholder.png +0 -0
  7. package/.claude/skills/multigrid-poster/shared/fonts/MaShanZheng-Regular.ttf +0 -0
  8. package/.claude/skills/video-edit/SKILL.md +189 -0
  9. package/.claude/skills/video-gen/SKILL.md +722 -0
  10. package/.claude/skills/video-gen/templates/INDEX.md +78 -0
  11. package/.claude/skills/video-gen/templates/before-after-beauty.md +183 -0
  12. package/.claude/skills/video-gen/templates/drama-fmcg.md +183 -0
  13. package/.claude/skills/video-gen/templates/kol-reaction-food.md +193 -0
  14. package/.claude/skills/video-gen/templates/multi-point-apparel.md +185 -0
  15. package/.claude/skills/video-gen/templates/pain-solution-home.md +184 -0
  16. package/.claude/skills/video-gen/templates/pdp-360-showcase.md +189 -0
  17. package/.claude/skills/video-gen/templates/pdp-feature-highlight.md +182 -0
  18. package/.claude/skills/video-gen/templates/scene-digital.md +183 -0
  19. package/dist/commands/avatar.d.ts +9 -0
  20. package/dist/commands/avatar.d.ts.map +1 -0
  21. package/dist/commands/avatar.js +155 -0
  22. package/dist/commands/avatar.js.map +1 -0
  23. package/dist/commands/doctor.d.ts +9 -0
  24. package/dist/commands/doctor.d.ts.map +1 -0
  25. package/dist/commands/doctor.js +293 -0
  26. package/dist/commands/doctor.js.map +1 -0
  27. package/dist/commands/voice.d.ts +9 -0
  28. package/dist/commands/voice.d.ts.map +1 -0
  29. package/dist/commands/voice.js +123 -0
  30. package/dist/commands/voice.js.map +1 -0
  31. package/dist/index.js +7 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/services/generation-api.d.ts +69 -3
  34. package/dist/services/generation-api.d.ts.map +1 -1
  35. package/dist/services/generation-api.js +92 -0
  36. package/dist/services/generation-api.js.map +1 -1
  37. package/package.json +4 -3
@@ -0,0 +1,345 @@
1
+ ---
2
+ name: gen
3
+ description: "生成和编辑图片/语音/虚拟试穿。使用场景:生成图片(generate images/生成图片/画图)、编辑图片(edit images/编辑图片/图生图/风格转换)、文本转语音(TTS/语音合成/朗读)、语音识别(ASR/语音转文字/转录)、虚拟试穿(virtual try-on/试穿/换装/试衣)。视频生成请使用 video-gen skill。"
4
+ version: 1.0.0
5
+ owner_repo: Optima-Chat/optima-gen
6
+ ---
7
+
8
+ # AI 内容生成工具
9
+
10
+ ## 图片生成
11
+
12
+ ### 标准工作流程
13
+
14
+ ```bash
15
+ # 文生图
16
+ gen image "提示词" -o /home/aiuser/project/result.png
17
+
18
+ # 图片编辑/风格转换
19
+ gen image "转成水彩风格" -i photo.png -o /home/aiuser/project/result.png
20
+
21
+ # 读取并描述结果
22
+ Read /home/aiuser/project/result.png
23
+ ```
24
+
25
+ ### gen image 命令
26
+
27
+ 统一的图像生成/编辑命令。
28
+
29
+ ```bash
30
+ gen image <prompt> [options]
31
+ ```
32
+
33
+ #### 参数
34
+
35
+ | 参数 | 说明 |
36
+ |------|------|
37
+ | `-i, --input <path>` | 输入图像(可多次使用,最多 8 张) |
38
+ | `-W, --width <px>` | 输出宽度(默认 1024,最大 2048) |
39
+ | `-H, --height <px>` | 输出高度(默认 1024,最大 2048) |
40
+ | `-o, --output <path>` | 输出目录或完整路径 |
41
+ | `-s, --seed <number>` | 随机种子(可复现结果) |
42
+ | `-f, --format <fmt>` | 输出格式:jpeg \| png |
43
+ | `--provider <name>` | 供应商:grsai(默认) \| bfl |
44
+ | `-m, --model <model>` | 模型:gpt-image-2(默认) \| nano-banana-fast \| nano-banana-pro \| flux-kontext-pro \| flux-kontext-max 等 |
45
+ | `--aspect-ratio <ratio>` | 宽高比:1:1 \| 16:9 \| 9:16 \| 4:3 等 |
46
+ | `--image-size <size>` | nano-banana-pro 输出尺寸:1K \| 2K \| 4K |
47
+
48
+ ### 工作流示例
49
+
50
+ #### 文生图
51
+
52
+ ```bash
53
+ gen image "a cute fluffy cat sitting on a windowsill, natural lighting" -o /home/aiuser/project/cat.png
54
+ Read /home/aiuser/project/cat.png
55
+ ```
56
+
57
+ #### 图片风格转换
58
+
59
+ ```bash
60
+ gen image "watercolor painting style, artistic brushstrokes" -i photo.jpg -o /home/aiuser/project/watercolor.png
61
+ Read /home/aiuser/project/watercolor.png
62
+ ```
63
+
64
+ #### 多图风格融合
65
+
66
+ 将第一张图的风格应用到第二张图的内容上:
67
+
68
+ ```bash
69
+ gen image "apply the artistic style from image 1 to the content of image 2" -i style.png -i content.png -o /home/aiuser/project/fusion.png
70
+ Read /home/aiuser/project/fusion.png
71
+ ```
72
+
73
+ #### 多图元素组合
74
+
75
+ 从多张图中提取元素组合成新图:
76
+
77
+ ```bash
78
+ gen image "The person from image 1 is petting the cat from image 2, in a cozy living room" -i person.jpg -i cat.jpg -o /home/aiuser/project/combined.png
79
+ ```
80
+
81
+ #### 精确颜色控制
82
+
83
+ 使用 hex code 指定精确颜色:
84
+
85
+ ```bash
86
+ gen image "a modern logo with brand color #02eb3c as the primary accent" -o /home/aiuser/project/logo.png
87
+ ```
88
+
89
+ #### 产品海报
90
+
91
+ ```bash
92
+ gen image "Disney Pixar style 3D poster, [产品描述], cute character, vibrant gradient background, professional studio lighting" -W 1024 -H 1024 -o /home/aiuser/project/poster.png
93
+ ```
94
+
95
+ ### 提示词指南
96
+
97
+ #### 结构
98
+
99
+ **Subject + Action + Style + Context**
100
+
101
+ 词序很重要,靠前的元素优先级更高。
102
+
103
+ #### 长度建议
104
+
105
+ | 长度 | 词数 | 适用场景 |
106
+ |------|------|----------|
107
+ | 短 | 10-30 | 快速概念探索 |
108
+ | 中 | 30-80 | 大多数项目(推荐) |
109
+ | 长 | 80+ | 复杂场景 |
110
+
111
+ #### 最佳实践
112
+
113
+ | 技巧 | 说明 | 示例 |
114
+ |------|------|------|
115
+ | 描述想要的 | 不支持负向提示词 | "sharp focus" 而非 "no blur" |
116
+ | 精确颜色 | 使用 hex code | `"brand color #1a1a2e"` |
117
+ | 文字渲染 | 用引号包裹文字 | `"The text 'OPEN' in red neon"` |
118
+ | 摄影风格 | 指定相机/镜头 | `"shot on Fujifilm X-T5, 35mm f/1.4"` |
119
+ | 多语言 | 用原生语言更地道 | 法语描述巴黎场景 |
120
+
121
+ #### 示例对比
122
+
123
+ ```bash
124
+ # 简单
125
+ gen image "a robot"
126
+
127
+ # 添加风格
128
+ gen image "a friendly AI robot, cute cartoon style, bright colors, 3D render"
129
+
130
+ # 完整描述
131
+ gen image "Disney Pixar style 3D animated robot character, friendly cheerful expression, wearing headset, surrounded by floating icons, gradient purple-blue background, professional studio lighting, vibrant colors"
132
+ ```
133
+
134
+ ### 分辨率选择
135
+
136
+ 最大 2048x2048。
137
+
138
+ | 用途 | 分辨率 |
139
+ |------|--------|
140
+ | 社交媒体 | 1024x1024 |
141
+ | 宽屏壁纸 | 1920x1088 |
142
+ | 竖屏海报 | 768x1280 |
143
+
144
+ ### 生成规则
145
+
146
+ #### 生成后
147
+ - 使用 Read 工具查看生成的图片
148
+ - 向用户描述图片内容(颜色、风格、构图、元素)
149
+ - 验证是否符合用户要求
150
+
151
+ #### 多图参考
152
+ - 最多 8 张输入图
153
+
154
+ ## 虚拟试穿 (Virtual Try-On)
155
+
156
+ 使用 FASHN AI tryon-v1.6 将服装穿到人物照片上。
157
+
158
+ ```bash
159
+ gen tryon <人物照片> <服装照片> [options]
160
+ ```
161
+
162
+ ### 参数
163
+
164
+ | 参数 | 说明 | 默认值 |
165
+ |------|------|--------|
166
+ | `-o, --output <path>` | 输出文件路径 | `./gen-output/tryon_{timestamp}.png` |
167
+ | `-c, --category <type>` | 服装类别:auto \| tops \| bottoms \| one-pieces | auto |
168
+ | `-m, --mode <mode>` | 生成模式:performance \| balanced \| quality | quality |
169
+ | `--garment-type <type>` | 服装照片类型:auto \| flat-lay \| model | auto |
170
+ | `-n, --num-samples <n>` | 生成数量 (1-4) | 1 |
171
+ | `--format <fmt>` | 输出格式:png \| jpeg | png |
172
+ | `--seed <n>` | 随机种子(可复现) | - |
173
+
174
+ ### 示例
175
+
176
+ ```bash
177
+ # 基本用法
178
+ gen tryon person.jpg garment.jpg -o /home/aiuser/project/result.png
179
+ Read /home/aiuser/project/result.png
180
+
181
+ # 使用 URL 图片
182
+ gen tryon https://example.com/model.jpg https://example.com/dress.jpg -o /home/aiuser/project/result.png
183
+
184
+ # 指定服装类别和快速模式
185
+ gen tryon person.jpg top.jpg -c tops -m performance -o /home/aiuser/project/result.png
186
+
187
+ # 生成多张结果
188
+ gen tryon person.jpg dress.jpg -n 4 -c one-pieces -o /home/aiuser/project/result.png
189
+ ```
190
+
191
+ ### 注意事项
192
+
193
+ - 支持本地图片路径和 URL
194
+ - 服装类别:auto (自动检测), tops (上装), bottoms (下装), one-pieces (连体)
195
+ - 三种模式:performance (~7s), balanced (~9s), quality (~13s)
196
+ - 默认保存到 `./gen-output/`
197
+
198
+ ## 语音合成 (TTS)
199
+
200
+ 使用 DashScope qwen3-tts-flash 将文本转为语音。
201
+
202
+ ```bash
203
+ gen tts <文本> [options]
204
+ ```
205
+
206
+ ### 参数
207
+
208
+ | 参数 | 说明 | 默认值 |
209
+ |------|------|--------|
210
+ | `-o, --output <path>` | 输出文件路径 | `./gen-output/tts_{timestamp}.wav` |
211
+ | `--voice <name>` | 声音名称 | Cherry |
212
+ | `--voices` | 列出可用声音 | - |
213
+ | `--play` | 生成后自动播放 | - |
214
+
215
+ ### 可用声音
216
+
217
+ - 女声:Cherry, Serena, Chelsie, Aria, Bella, Vivian, Jennifer, Katerina, Breeze, Maple, Sakura
218
+ - 男声:Ethan, Aiden, Brandon, Ryan, Luke, Leo
219
+
220
+ ### 示例
221
+
222
+ ```bash
223
+ # 中文语音合成
224
+ gen tts "你好,欢迎使用语音合成功能" -o /home/aiuser/project/hello.wav
225
+
226
+ # 指定男声
227
+ gen tts "Hello, welcome!" --voice Ethan -o /home/aiuser/project/greeting.wav
228
+
229
+ # 生成后播放
230
+ gen tts "测试语音" --play -o /home/aiuser/project/test.wav
231
+ ```
232
+
233
+ ### 注意事项
234
+
235
+ - 输出格式为 WAV
236
+ - 最大 5000 字符
237
+ - 支持中、英、日、韩、法、德等 10 种语言(自动检测)
238
+ - 默认保存到 `./gen-output/`
239
+
240
+ ## 语音识别 (ASR)
241
+
242
+ 使用 Groq Whisper 将语音转为文字。
243
+
244
+ ```bash
245
+ gen asr <音频文件> [options]
246
+ ```
247
+
248
+ ### 参数
249
+
250
+ | 参数 | 说明 | 默认值 |
251
+ |------|------|--------|
252
+ | `--language <lang>` | 语言提示:zh \| en \| ja \| ko 等 | 自动检测 |
253
+ | `--model <name>` | Whisper 模型 | whisper-large-v3-turbo |
254
+
255
+ ### 示例
256
+
257
+ ```bash
258
+ # 自动检测语言
259
+ gen asr /home/aiuser/project/recording.mp3
260
+
261
+ # 指定语言提示(提高准确率)
262
+ gen asr /home/aiuser/project/recording.wav --language zh
263
+ ```
264
+
265
+ ### 注意事项
266
+
267
+ - 支持 mp3, wav, m4a, ogg, webm 格式
268
+ - 文件大小限制 25MB
269
+
270
+ ## 任务管理
271
+
272
+ 所有生成命令会自动等待完成。如需查看历史或管理任务:
273
+
274
+ ```bash
275
+ gen task list # 查看所有任务
276
+ gen task list --type image # 按类型过滤
277
+ gen task list --status failed # 按状态过滤
278
+ gen task get <task_id> # 查看任务详情
279
+ gen task cancel <task_id> # 取消任务
280
+ gen task retry <task_id> # 重试失败的任务
281
+ ```
282
+
283
+ ## 错误处理(重要)
284
+
285
+ 所有 `gen` 命令在失败时会返回结构化错误。**不要把原始 `error_message` 直接抛给用户**——根据 `error_class` 字段决定应对策略。
286
+
287
+ ### 失败响应示例
288
+
289
+ ```json
290
+ {
291
+ "success": true,
292
+ "data": {
293
+ "task_id": "abc-123",
294
+ "status": "failed",
295
+ "error_code": "CONTENT_POLICY_VIOLATION",
296
+ "error_class": "prompt_problem",
297
+ "retryable": false,
298
+ "error_message": "生成内容被审核拒绝,请调整描述后重试(不会重复扣费)"
299
+ }
300
+ }
301
+ ```
302
+
303
+ 注意:`success: true` + `status: "failed"` 是任务执行完成但生成失败;`success: false` 才是 CLI 调用本身失败。两者都要按 `error_class` / `error_code` 处理。
304
+
305
+ ### 主决策字段:`error_class`(4 值枚举)
306
+
307
+ **优先看 `error_class`** 决定大方向,再看 `error_code` 决定细节话术。新增 `error_code` 时 `error_class` 不变,向后兼容。
308
+
309
+ | `error_class` | 含义 | 你应该做的 |
310
+ |---|---|---|
311
+ | `retry_safe` | 上游瞬时问题(超时 / 限流 / 维护 / 网络) | 等会原样重试**最多 1 次**,静默或简短告知 |
312
+ | `prompt_problem` | 用户输入被拒(违规 / 格式不对) | 调整 prompt 或换素材,**自动重试最多 1 次**;仍失败交给用户 |
313
+ | `provider_problem` | 平台后端问题(账户额度耗尽等) | **不重试**。明确告诉用户问题不在他、不在他的余额 |
314
+ | `unknown` | 未识别错误 | **不重试**。把通用错误信息透给用户,建议联系支持 |
315
+
316
+ ### 处理对照表(细分 `error_code`)
317
+
318
+ | `error_code` | `error_class` | 你应该做的 | 给用户的话术(参考) |
319
+ |---|---|---|---|
320
+ | `UPSTREAM_MAINTENANCE` | `retry_safe` | **不立即重试**。告知用户服务维护中,建议 5-10 分钟后再试 | "图片生成服务正在维护,建议 5-10 分钟后我再帮您试一次" |
321
+ | `UPSTREAM_TIMEOUT` | `retry_safe` | 立即重试 1 次(静默) | (重试成功就别提;连续失败再说) |
322
+ | `UPSTREAM_RATE_LIMITED` | `retry_safe` | 等 30 秒后重试 1 次 | "请求频率过高,稍等几十秒再试" |
323
+ | `UPSTREAM_NETWORK` | `retry_safe` | 立即重试 1 次(静默) | (同 timeout) |
324
+ | `CONTENT_POLICY_VIOLATION` | `prompt_problem` | **改写 prompt** 去掉敏感/违规元素,自动重试**最多 1 次**。仍失败再交给用户 | "您的描述触发了内容审核,我换个说法重试:……" |
325
+ | `INVALID_INPUT` | `prompt_problem` | **不要原样重试**。提示用户输入素材有问题(如图片格式不支持),建议更换 | "您提供的参考图格式不支持,请用 JPG/PNG/WEBP 等常见格式重试" |
326
+ | `PROVIDER_INSUFFICIENT_CREDITS` | `provider_problem` | **不重试**。明确告诉用户问题不在他、不在他的余额 | "生成服务后端额度不足(与您账户余额无关),已记录" |
327
+ | `PROVIDER_AUTH_FAILED` | `provider_problem` | **不重试**。配置/认证问题(API key 错或账户被封),跟用户余额无关,已交管理员处理 | "生成服务认证失败,已记录并将由管理员处理。此问题与您的账户无关" |
328
+ | `UPSTREAM_UNKNOWN` 或字段缺失 | `unknown` | **不重试**。把 `error_message` 透传给用户 | "图片生成失败:{error_message}" |
329
+
330
+ ### 通用规则
331
+
332
+ 1. **优先按 `error_class` 决策**,遇到不认识的 `error_code` 也能正确分流
333
+ 2. **`retryable: true`** 的失败:自动重试**最多 1 次**,不要循环
334
+ 3. **`retryable: false`**:永远不重试,立即给用户结果
335
+ 4. 改写 prompt 重试时,**告诉用户你做了什么改动**(透明)
336
+ 5. `success: false`(CLI 本身报错)直接报给用户,不重试
337
+ 6. 没有 `error_class` / `error_code` 字段的旧版响应:当作 `unknown` / `UPSTREAM_UNKNOWN` 处理
338
+
339
+ ### 反面示例(不要这样做)
340
+
341
+ ❌ 把 `"维护中"` 三个字直接砸给用户
342
+ ❌ 任何失败都自动 retry 三五次造成账单浪费
343
+ ❌ `CONTENT_POLICY_VIOLATION` 时换汤不换药地原 prompt 重试
344
+ ❌ `INVALID_INPUT` 时反复用同一份格式不对的图重试
345
+ ❌ `PROVIDER_INSUFFICIENT_CREDITS` 时让用户去充值(这跟用户余额无关)
@@ -0,0 +1,194 @@
1
+ ---
2
+ name: multigrid-poster
3
+ description: "为商家生成小红书 2×2 四宫格 / 3×3 九宫格封面图。触发场景:做小红书封面 / 小红书首图 / 种草帖封面 / 爆款封面 / 四宫格 / 九宫格。一句话指令产出 1242×1660 成片,支持自然语言迭代(换版式 / 重抽某格 / 改文案)。本 skill 只生成封面图,搜索小红书笔记 / 分析博主请用 'xhs' skill。"
4
+ version: 1.0.0
5
+ owner_repo: Optima-Chat/optima-gen
6
+ ---
7
+
8
+ # 小红书多宫格封面生成
9
+
10
+ 帮电商商家用 AI 图 + 通用网格布局合成小红书封面。**一句话从意图到 1242×1660 成片**,支持 4 宫格 / 9 宫格两种版式。
11
+
12
+ ## Global Rules
13
+
14
+ 优先级高于任何 pipeline 步骤。
15
+
16
+ 1. **User-facing 不出现模型名 / 服务名**
17
+ status / 成本 / 进度统一用"封面生成中 / 素材生成中 / 合成封面中"。`gen image` 作为 CLI 字面值可以,但不要把整条命令原文回显给用户。
18
+
19
+ 2. **花钱前必走 COST-GATE**
20
+ 任何 `gen image` 批量调用之前必走一次成本确认。**Fast-path、迭代、重试均无例外**。2×2 = 4 张,3×3 = 9 张,SKU 拉图 = 0 张。rate 按 `gen image` 每次 1 积分估。
21
+
22
+ 3. **Per-post init 是任何 pipeline 第一步**
23
+ 出图 / 合成执行前先建目录 + cd。否则 write 写错位置。迭代场景用 `{旧id}-vN`。
24
+
25
+ 4. **Anti-fabrication**
26
+ 未在本 skill 显式列出的命令 / flag / 参数,不允许凭印象拼。`gen image` / `commerce` / `compose.py` 子命令同样适用。
27
+
28
+ 5. **不自动发帖**
29
+ 只产 PNG,**绝对不调用**任何自动登录 / 发帖 / 上传命令。完成后给路径,用户自己下载手动发。
30
+
31
+ ## 工作目录
32
+
33
+ ```
34
+ ~/multigrid-poster/
35
+ ├── preferences.md
36
+ ├── history.md
37
+ └── posters/{post-id}/
38
+ ├── intent.md # 用户意图 + layout + 文案
39
+ ├── cells/cell_0..N.png # 4 或 9 张素材
40
+ ├── cover.png # 成片
41
+ └── cost.md
42
+ ```
43
+
44
+ 整个 `~/multigrid-poster/` 是一个 git repo。每步完成后 `git add -A && git commit`。
45
+
46
+ ## 启动流程
47
+
48
+ 1. **首次** (`ls ~/multigrid-poster/preferences.md` 不存在) → `mkdir -p ~/multigrid-poster/posters && cd ~/multigrid-poster && git init -b main`,创建空的 `preferences.md` (字段:merchant_id / brand_name / category / xhs_account_id / default_layout) 和 `history.md` (表头:date | post-id | layout | title | parent | status)。`.gitignore` 加 `posters/**/cells/*.png` 和 `posters/**/cover.png`。
49
+ 2. **扫未完成**:`posters/` 下有 `intent.md` 但无 `cover.png` 且 < 7 天 → 提一次"你有 N 个封面没完成"。
50
+ 3. **读 preferences.md / history.md**,继续主流程。
51
+
52
+ ## 主流程
53
+
54
+ ### Step 1: 选 layout
55
+
56
+ | 用户原话 | layout | cells |
57
+ |---|---|---|
58
+ | 含"九宫格 / 9 格 / 9 张 / 清单 / N 款 / 礼物推荐 / 榜单" | **3×3** | 9 |
59
+ | 其他(包含"四宫格 / 4 格 / 4 张" 或没指定) | **2×2** | 4 |
60
+
61
+ ### Step 2: Per-post init
62
+
63
+ ```bash
64
+ # slug = 用户意图前 20 字内的 kebab-case
65
+ POST_ID="$(date +%Y%m%d-%H%M)-<slug>"
66
+ mkdir -p ~/multigrid-poster/posters/$POST_ID/cells
67
+ cd ~/multigrid-poster/posters/$POST_ID
68
+ ```
69
+
70
+ 迭代("换版式 / 重抽 / 改文案")时:轻迭代沿用旧目录,重迭代新建 `{旧id}-vN`。
71
+
72
+ ### Step 3: 写文案
73
+
74
+ agent 自己写,不调外部生成器。约束:
75
+ - **title**:2 行 × 8-12 字 / 行(2×2 适合)或 2 行 × 6-10 字 / 行(3×3 标题挤)
76
+ - **caption**:2 行 × 15-20 字 / 行
77
+ - 硬禁:医疗 / 保健 / 绝对化用语(最 / 第一 / 唯一 / 100%)
78
+
79
+ 写到 `intent.md`:
80
+
81
+ ```markdown
82
+ # Intent
83
+ | 项目 | 值 |
84
+ |---|---|
85
+ | 用户原话 | <原话> |
86
+ | layout | 2x2 / 3x3 |
87
+ | title 行 1 | <8-12 字> |
88
+ | title 行 2 | <8-12 字> |
89
+ | caption 行 1 | <15-20 字> |
90
+ | caption 行 2 | <15-20 字> |
91
+ ```
92
+
93
+ 展示给用户:"标题'XXX / YYY',副标题'AAA / BBB'。OK 吗?"
94
+ - Fast-path(意图明确):告知,用户喊停才停
95
+ - 意图模糊:必须等确认
96
+
97
+ ### Step 4: COST-GATE
98
+
99
+ **生成前必做**(包括 Fast-path / 迭代 / 重试):
100
+
101
+ > 即将生成封面(布局: 2x2 / 3x3),预计:
102
+ > - 素材调用: N 次(2×2=4 / 3×3=9 / SKU 拉图=0)
103
+ > - 预估耗时: ~X 分钟
104
+ > - 预估成本: ~Y 积分
105
+ >
106
+ > 继续?
107
+
108
+ 用户说"继续 / 好" → 执行。"太贵 / 换便宜的" → 提议降级 (3×3 → 2×2,或 SKU 拉图)。不回应 → 等。
109
+
110
+ ### Step 5: 出图
111
+
112
+ **默认走 AI 生图**。每个 cell 并行调一次:
113
+
114
+ ```bash
115
+ # 2×2: cell 尺寸 621×830;3×3: cell 尺寸 414×420
116
+ gen image "<subprompt>" -W <W> -H <H> -o ./cells/cell_<i>.png -s <seed> -f png
117
+ ```
118
+
119
+ `<subprompt>` 由 agent 根据用户意图为每格独立设计(不同视角 / 不同 step / 不同场景 / 不同 SKU 等)。`<seed>` 用确定性 hash(POST_ID + cell_index),迭代复用同格 seed。
120
+
121
+ **SKU 拉图模式**(用户明确说"用我店里商品图"做 listicle):
122
+
123
+ ```bash
124
+ commerce product list --limit 9
125
+ ```
126
+
127
+ 下载到 `./cells/cell_0..8.png`。商品 < 9 → 降级 2×2 取前 4。商品 < 4 → 报错。
128
+
129
+ **失败容忍**:单格生图失败 → 重试 1 次(换 seed)。两次失败 → 用 `${CLAUDE_SKILL_DIR}/scripts/placeholder.png` 占位,告知用户"第 N 格失败,先占位,要重抽直接说"。
130
+
131
+ ### Step 6: 合成
132
+
133
+ ```bash
134
+ python3 $CLAUDE_SKILL_DIR/scripts/compose.py \
135
+ --layout $CLAUDE_SKILL_DIR/layouts/2x2.json \
136
+ --cells ./cells/cell_0.png ./cells/cell_1.png ... \
137
+ --title-line "<title 行 1>" \
138
+ --title-line "<title 行 2>" \
139
+ --caption-line "<caption 行 1>" \
140
+ --caption-line "<caption 行 2>" \
141
+ --output ./cover.png
142
+ ```
143
+
144
+ 依赖:Pillow(容器自带)。失败常见原因:
145
+
146
+ | 错误 | 处理 |
147
+ |---|---|
148
+ | `cell 数量不对` | layout 要求 4 / 9,检查 `--cells` 参数 |
149
+ | `font not found` | 检查 `$CLAUDE_SKILL_DIR/shared/fonts/` 完整 |
150
+ | 中文显示方块 | 同上,字体没加载 |
151
+
152
+ ### Step 7: 交付
153
+
154
+ 写 `cost.md`,追加 `~/multigrid-poster/history.md` 一行,告知用户:
155
+
156
+ > 封面在 `~/multigrid-poster/posters/<POST_ID>/cover.png`,可以下载发帖了。
157
+ > 换版式 / 改文案 / 重抽某格直接告诉我。
158
+
159
+ 用户说"好 / 完美" → preferences.md `Learned` 追加一条 → commit。
160
+
161
+ ## 迭代
162
+
163
+ | 类型 | 重跑步骤 | 新目录 | 成本 |
164
+ |---|---|---|---|
165
+ | 换 layout(2×2 ↔ 3×3) | 文案 → 出图 → 合成 | 是(`-vN`) | 全成本 |
166
+ | 重抽全部 | 出图 → 合成 | 是 | 全素材 |
167
+ | 重抽单格 N | 出图(单格) → 合成 | 否 | 1 素材 |
168
+ | 改文案 | 合成 | 否 | 0 |
169
+
170
+ **每次迭代也走 COST-GATE**,即使 0 积分。
171
+
172
+ ## 错误处理
173
+
174
+ | 故障 | 处理 |
175
+ |---|---|
176
+ | `gen image` 返回 failed | 重试 1 次换 seed → 仍失败用占位图 |
177
+ | 超配额 / 余额不足 | 告知用户,不自动降级 |
178
+ | `commerce product list` < 9 | 降级 2×2 取前 4 |
179
+ | 会话关闭 | 状态在文件系统 + git,下次接续 |
180
+
181
+ ## 相关工具
182
+
183
+ - `gen image` — 文生图(详见 `gen` skill)
184
+ - `commerce merchant get` / `commerce product list` — 商家档案 / 商品(详见 `merchant` skill 和 `product` skill)
185
+ - `compose.py` — 本 skill 自带的 Pillow 渲染器
186
+
187
+ ## 流程偏好
188
+
189
+ - **信息够就直接做(Fast-path)**
190
+ - **`intent.md` 是可追溯产物**
191
+ - **每步完成立刻 git commit**
192
+ - **生成过程零打扰**
193
+ - **迭代用 `-vN` 不覆盖**
194
+ - **新会话有未完成先告知一次**
@@ -0,0 +1,34 @@
1
+ {
2
+ "_comment": "通用 2×2 网格布局 — 适合 4 张 cell 的所有 intent (创业故事/对比测评/教程/场景)",
3
+ "canvas_size": [1242, 1660],
4
+ "cells": {
5
+ "positions": [[0, 0], [621, 0], [0, 830], [621, 830]],
6
+ "sizes": [[621, 830], [621, 830], [621, 830], [621, 830]]
7
+ },
8
+ "text_zones": {
9
+ "title": {
10
+ "_comment": "中央偏上 2 行标题 - 8-12 字 / 行最佳",
11
+ "font": "shared/fonts/MaShanZheng-Regular.ttf",
12
+ "size": 110,
13
+ "color": "#FFB940",
14
+ "stroke_w": 8,
15
+ "stroke_color": "#D63D3D",
16
+ "lines": [
17
+ {"position": [621, 480], "anchor": "mm"},
18
+ {"position": [621, 620], "anchor": "mm"}
19
+ ]
20
+ },
21
+ "caption": {
22
+ "_comment": "底部 2 行 caption - 15-20 字 / 行最佳",
23
+ "font": "shared/fonts/MaShanZheng-Regular.ttf",
24
+ "size": 78,
25
+ "color": "#FFB940",
26
+ "stroke_w": 6,
27
+ "stroke_color": "#D63D3D",
28
+ "lines": [
29
+ {"position": [621, 1340], "anchor": "mm"},
30
+ {"position": [621, 1450], "anchor": "mm"}
31
+ ]
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "_comment": "通用 3×3 网格布局 - 适合 9 张 cell (商品清单 / 多角度展示)",
3
+ "canvas_size": [1242, 1660],
4
+ "cells": {
5
+ "_comment": "9 格 414×420。顶部 200px 标题区,cells y=200..1460,底部 200px caption 区。3×420 + 200×2 = 1660 = canvas_h ✓",
6
+ "positions": [
7
+ [0, 200], [414, 200], [828, 200],
8
+ [0, 620], [414, 620], [828, 620],
9
+ [0, 1040], [414, 1040], [828, 1040]
10
+ ],
11
+ "sizes": [
12
+ [414, 420], [414, 420], [414, 420],
13
+ [414, 420], [414, 420], [414, 420],
14
+ [414, 420], [414, 420], [414, 420]
15
+ ]
16
+ },
17
+ "text_zones": {
18
+ "title": {
19
+ "_comment": "顶部白边 2 行标题(y < 200 区间)",
20
+ "font": "shared/fonts/MaShanZheng-Regular.ttf",
21
+ "size": 78,
22
+ "color": "#FFB940",
23
+ "stroke_w": 6,
24
+ "stroke_color": "#D63D3D",
25
+ "lines": [
26
+ {"position": [621, 60], "anchor": "mm"},
27
+ {"position": [621, 150], "anchor": "mm"}
28
+ ]
29
+ },
30
+ "caption": {
31
+ "_comment": "底部白边 2 行 caption(cells 结束于 y=1460,留 200px)",
32
+ "font": "shared/fonts/MaShanZheng-Regular.ttf",
33
+ "size": 60,
34
+ "color": "#FFB940",
35
+ "stroke_w": 5,
36
+ "stroke_color": "#D63D3D",
37
+ "lines": [
38
+ {"position": [621, 1530], "anchor": "mm"},
39
+ {"position": [621, 1610], "anchor": "mm"}
40
+ ]
41
+ }
42
+ }
43
+ }