完善小红书卡片与 GitHub 交付流程
parent
79c1968950
commit
81a4173155
58
README.md
58
README.md
|
|
@ -1,8 +1,8 @@
|
|||
# MAOMOMO 文章生成器
|
||||
|
||||
这是一个面向 Codex 的中文写作技能,用来生成 MAOMOMO / 猫MOMO 风格的出海金融实操文章、文章大纲、发布用 Markdown、SEO 优化稿、独立配图 assets 和 ZIP 发布包。
|
||||
这是一个面向 Codex 的中文写作技能,用来生成 MAOMOMO / 猫MOMO 风格的出海金融实操文章、文章大纲、发布用 Markdown、SEO 优化稿、独立配图 assets、ZIP 发布包,以及小红书卡片 / 多图 / 3:4 / 9:16 竖版 PNG 交付。
|
||||
|
||||
新版流程参考了 `codex-ppt-skill` 的阶段化设计:先确认来源和文章口径,再确认大纲与配图规划,最后写作、生成配图、QA 和打包交付。这样可以降低金融活动文章里最常见的翻车点:旧规则混入新稿、来源没读全、图片残留旧口径、只给正文不交付文件。
|
||||
新版流程参考了 `codex-ppt-skill` 的阶段化设计:先确认来源和文章口径,再确认大纲 / 卡片结构与配图规划,最后写作或整理小红书文案、生成配图、QA、写入 `final_manifest.json`,并按渠道打包或 GitHub 分批交付。这样可以降低金融活动文章里最常见的翻车点:旧规则混入新稿、来源没读全、图片残留旧口径、只给正文不交付文件。
|
||||
|
||||
## 适用场景
|
||||
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
- 开户教程、保号教程、转账 / 入金 / 出金教程
|
||||
- 美股券商、数字货币、欧元通道、汇款路径
|
||||
- 避坑经验、实测记录、活动规则整理
|
||||
- MAOMOMO 风格封面图、截图槽位和信息图提示词
|
||||
- MAOMOMO 风格封面图、截图槽位、信息图和小红书卡片
|
||||
|
||||
不适合直接生成投资建议、法律意见、税务结论或任何“保证获批 / 稳赚 / 一定到账”的承诺型内容。
|
||||
|
||||
|
|
@ -33,8 +33,9 @@ maomomo-article-writer/
|
|||
├── visual-assets.md # 配图清单、视觉规则和图片 QA
|
||||
├── recommended-styles.md # 推荐配图风格和提示词片段
|
||||
├── image-styles/ # 参考 codex-ppt 风格库拆分的出图风格 brief
|
||||
├── image-generation.md # 图片生成脚本、manifest 和后端选择
|
||||
└── delivery-rules.md # 完整交付、打包和最终检查
|
||||
├── image-generation.md # 图片生成脚本、manifest、final_manifest 和后端选择
|
||||
├── github-delivery.md # GitHub 交付仓库、专用 KEY 和推送门禁
|
||||
└── delivery-rules.md # 完整交付、GitHub 分批、打包和最终检查
|
||||
```
|
||||
|
||||
## 安装方式
|
||||
|
|
@ -69,6 +70,10 @@ maomomo-article-writer
|
|||
把这个银行活动整理成猫MOMO风格文章,重点写怎么吃满和常见翻车点。
|
||||
```
|
||||
|
||||
```text
|
||||
把这个活动做成小红书 3:4 多图卡片,先给我确认 2D / 3D 视觉方向。
|
||||
```
|
||||
|
||||
## 推荐提示词
|
||||
|
||||
生成完整文章:
|
||||
|
|
@ -91,6 +96,18 @@ maomomo-article-writer
|
|||
使用 $maomomo-article-writer,为【主题】生成 MAOMOMO 风格封面图提示词、正文截图槽位和一张信息图提示词。不要写完整正文。
|
||||
```
|
||||
|
||||
小红书卡片:
|
||||
|
||||
```text
|
||||
使用 $maomomo-article-writer,做一组小红书 9:16 多图卡片。默认 2D 扁平风,要求每张独立 PNG,最后走 GitHub 分批交付。
|
||||
```
|
||||
|
||||
GitHub 交付配置:
|
||||
|
||||
```text
|
||||
使用 $maomomo-article-writer,先引导我配置 GitHub 交付仓库和专用 KEY,之后小红书卡片都走 GitHub 分批交付。
|
||||
```
|
||||
|
||||
改写已有文章:
|
||||
|
||||
```text
|
||||
|
|
@ -117,18 +134,35 @@ maomomo-article-writer
|
|||
- `assets/` 独立 PNG 配图目录
|
||||
- `article_package.zip`
|
||||
|
||||
小红书卡片通常包含:
|
||||
|
||||
- 20 字内标题
|
||||
- 小红书正文和 3-6 个话题标签
|
||||
- 多张 3:4 或 9:16 独立 PNG
|
||||
- `prompts/`、`slide_jobs.json`、`slide_run_state.json`
|
||||
- `final_manifest.json`
|
||||
- GitHub 分批链接
|
||||
|
||||
GitHub 分批交付前,技能会先引导配置:
|
||||
|
||||
- 专用私有交付仓库,例如 `OWNER/maomomo-delivery`
|
||||
- `MAOMOMO_GITHUB_REPO`、`MAOMOMO_GITHUB_BRANCH`、`MAOMOMO_GITHUB_BASE_PATH`
|
||||
- GitHub CLI 登录、fine-grained PAT,或 SSH deploy key
|
||||
- 最小权限原则:只给交付仓库写入权限
|
||||
- 密钥不进入聊天、prompt、manifest、状态文件、README、日志或 commit
|
||||
|
||||
如果事实不完整,技能会使用 `【待确认:...】` 标记缺口,而不是编造数字、日期、奖励或链接。
|
||||
|
||||
## 默认流程
|
||||
|
||||
完整交付任务通常按以下步骤执行:
|
||||
|
||||
1. 识别任务模式:完整文章、大纲、SEO 优化、改稿、配图或小红书版。
|
||||
1. 识别任务模式:完整文章、大纲、SEO 优化、改稿、配图或小红书卡片。
|
||||
2. 读取来源并列出已读 / 未读材料,整理事实表和待确认项。
|
||||
3. 确认文章范围、大纲、标题方向、核心口径和图片规划。
|
||||
3. 确认文章范围、大纲 / 卡片结构、标题方向、核心口径和图片规划。
|
||||
4. 写作或优化发布用 Markdown。
|
||||
5. 确认配图风格,生成或准备独立 PNG 配图,插入 Markdown。
|
||||
6. 检查来源、图片路径、风险提示、编辑痕迹和 ZIP 内容,最后交付文件路径。
|
||||
5. 确认配图风格;小红书卡片需先确认 2D / 3D 和 3:4 / 9:16,再生成或准备独立 PNG。
|
||||
6. 检查来源、图片路径、风险提示、编辑痕迹、ZIP 或 `final_manifest.json`;需要 GitHub 交付时先确认仓库和专用 KEY 配置,最后交付文件路径或 GitHub 分批链接。
|
||||
|
||||
用户明确说“只要文字”“只要大纲”“不要图片”“不要打包”时,会按用户限制执行,不强行创建完整发布包。
|
||||
|
||||
|
|
@ -153,6 +187,7 @@ maomomo-article-writer
|
|||
- 涉及金融、券商、银行、数字货币和合规内容时,保留谨慎措辞
|
||||
- 配图统一使用白橘猫、暖橙色、干净金融科技教程风
|
||||
- 如果用户没有指定配图风格,先在 `recommended-styles.md` 和 `image-styles/` 中按文章类型推荐 2-3 个方向,例如 `clean-professional`、`data-card-dashboard`、`handdrawn-note`、`e-ink-editorial` 或 `xiaohongshu-vertical`。
|
||||
- 小红书卡片出图前必须确认 `2D 扁平风` / `3D 轻拟物风` 和 `3:4` / `9:16`;用户没指定时默认推荐 2D,并按原生竖版重新构图,不能把横版图压进竖图。
|
||||
|
||||
文章不应当:
|
||||
|
||||
|
|
@ -169,7 +204,8 @@ maomomo-article-writer
|
|||
- 配图类型、猫咪视觉、文件命名和图片 QA 写在 `references/visual-assets.md`。
|
||||
- 推荐配图风格、适用场景和提示词片段写在 `references/recommended-styles.md`。
|
||||
- 具体出图风格 brief 放在 `references/image-styles/`,结构参考 `codex-ppt-skill` 的风格库。
|
||||
- 图片 API/CLI fallback、批量 manifest 和脚本用法写在 `references/image-generation.md`,脚本为 `scripts/maomomo_image_gen.py`。
|
||||
- 完整交付、ZIP、附件和最终检查写在 `references/delivery-rules.md`。
|
||||
- 图片 API/CLI fallback、批量 manifest、final manifest、GitHub 批次记录和脚本用法写在 `references/image-generation.md`,脚本为 `scripts/maomomo_image_gen.py` 和 `scripts/maomomo_job_state.py`。
|
||||
- GitHub 交付仓库、专用 KEY / token / deploy key、环境变量、隐私边界和推送前检查写在 `references/github-delivery.md`。
|
||||
- 完整交付、ZIP、GitHub 分批、附件和最终检查写在 `references/delivery-rules.md`。
|
||||
- 修改技能展示名称或默认提示语时,同步更新 `agents/openai.yaml`。
|
||||
- 如果新增具体行业资料、平台规则或长期复用模板,优先放入 `references/`,避免让 `SKILL.md` 过长。
|
||||
|
|
|
|||
57
SKILL.md
57
SKILL.md
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
name: maomomo-article-writer
|
||||
description: 生成或优化符合 maomomo / 猫MOMO 风格的中文出海金融实操文章、发布用 Markdown、SEO 稿、配图规划、独立高清配图 assets 和 ZIP 发布包。适用于 maomomo.com、港卡、香港银行、香港信用卡、美股券商、数字货币、汇款、支付优化、返现活动、开户教程、保号教程、避坑经验、官方条款整理和实测攻略。用户要求使用 skill、按猫MOMO风格、完整文章、发布用 Markdown、配图、打包、一键下载或最终交付时触发。
|
||||
description: 生成或优化符合 maomomo / 猫MOMO 风格的中文出海金融实操文章、发布用 Markdown、SEO 稿、配图规划、独立高清配图 assets、ZIP 发布包,以及小红书卡片 / 多图 / 3:4 / 9:16 竖版 PNG 交付;包含 GitHub 交付仓库和专用 KEY / token / deploy key 配置引导。适用于 maomomo.com、港卡、香港银行、香港信用卡、美股券商、数字货币、汇款、支付优化、返现活动、开户教程、保号教程、避坑经验、官方条款整理和实测攻略。用户要求使用 skill、按猫MOMO风格、完整文章、发布用 Markdown、配图、打包、一键下载、最终交付、小红书、卡片、多图、3:4、9:16、GitHub 交付、仓库配置或专用 KEY 配置时触发。
|
||||
---
|
||||
|
||||
# MAOMOMO 文章生成器
|
||||
|
|
@ -16,6 +16,7 @@ description: 生成或优化符合 maomomo / 猫MOMO 风格的中文出海金融
|
|||
- 银行、港卡、香港信用卡、券商、数字货币、汇款、支付、账户维护、返现和羊毛活动。
|
||||
- 活动规则整理、开户教程、转账 / 入金 / 出金教程、保号方案、用卡姿势、对比总结、避坑经验。
|
||||
- 已有文章 SEO 优化、发布用 Markdown、配图规划、独立配图、ZIP 打包和后续改稿。
|
||||
- 小红书卡片、多图信息卡、3:4 或 9:16 竖版 PNG 系列图、封面 / 内容卡 / 结尾卡分批交付。
|
||||
|
||||
不适合:
|
||||
|
||||
|
|
@ -27,6 +28,7 @@ description: 生成或优化符合 maomomo / 猫MOMO 风格的中文出海金融
|
|||
|
||||
- 如果本技能任何旧规则与“确认优先、单步推进”的流程冲突,以本节和“默认工作流”中的阶段门禁为准。
|
||||
- 确认优先,单步推进;不要一上来就完整生成文章、全部配图或 ZIP。
|
||||
- 用户提到“小红书”“卡片”“多图”“3:4”“9:16”任一触发词时,默认进入“小红书卡片模式”:不默认走完整文章 + Markdown + ZIP 流程,输出重点改为多张独立 PNG、统一视觉风格、适合小红书发布。只有用户明确要求文章、Markdown 或 ZIP 时,才叠加对应交付物。
|
||||
- 读写 Markdown、JSON、CSV、HTML、代码或文本文件时显式使用 UTF-8。
|
||||
- 处理用户上传或提供的 Markdown / PDF / 官方链接 / 参考文章时,必须先完整读取或说明无法读取的部分,再写最终稿。
|
||||
- 费用、活动日期、奖励门槛、账户规则、返现、券商迎新、转账路径、数字货币出入金和合规事项,必须优先核查最新信息。优先级:用户提供的最新官方材料 > 官方页面 / 条款 PDF / App 显示 > 用户实测 > MAOMOMO 旧文 > 其他参考。
|
||||
|
|
@ -35,6 +37,8 @@ description: 生成或优化符合 maomomo / 猫MOMO 风格的中文出海金融
|
|||
- 写作前必须先给用户确认标题或标题方向、文章核心口径、`outline.md` 大纲、来源缺口、必选素材映射和配图风格。用户明确要求跳过确认时,未确认事实仍必须标 `【待确认:...】`。
|
||||
- 大纲未确认前,不得创建最终 `deck_spec.json`、`speech.md`、图片 prompt jobs、文章配图图片、ZIP 或用户指定的最终文章包。
|
||||
- 出图前必须先把全部图片 prompt 写入文件,包含文件名、用途、放置位置、核心文案、完整 prompt 和依赖素材;不要在聊天里输出超长 prompt。
|
||||
- 小红书卡片模式出图前必须先让用户确认视觉方向:`2D 扁平风` 或 `3D 轻拟物风`。用户没指定时,默认推荐 `2D 扁平风`,因为小红书信息图更稳、更不容易文字翻车;一旦确认,整组图片必须保持同一种视觉方向,不能中途混用。
|
||||
- 小红书竖图必须按原生竖版重新构图,禁止把横版设计硬塞进 3:4 或 9:16。每个小红书图片 prompt 必须包含英文约束:`native portrait composition`、`no squeezed elements`、`no stretched card / logo / text`、`vertical layout redesigned for Xiaohongshu`。
|
||||
- 图片 prompt 中的视觉风格只能作为后台画面描述,不得成为画面文字;prompt 必须限制可见文字只包含指定业务文案、`MAOMOMO` 和已核对允许出现的品牌 / 支付标识,不得出现风格标签、prompt 描述、额外 slogan 或无关文字。
|
||||
- 发布稿、图片文案、prompt、manifest 和 `deck_spec.json` 中金额统一写 `HKD`,不要使用港币符号;来源原文抽取文件可保留原文写法。
|
||||
- 金融活动配图如出现信用卡、支付卡、卡组织、支付网络或机构 Logo,必须按官方材料或用户素材核对并记录来源;用户没有提供 Logo / 卡面素材但画面需要品牌或支付标识时,应主动尽力从官方活动页、品牌资源页、条款 PDF、App / 官网截图等来源查找准确标识,保存到 `sources/` 并记录来源。不得把银联 / UnionPay 画成 Mastercard、Visa 等其他卡组织。已核对正确的 Mastercard / Visa / UnionPay / 银行 / 支付宝等标识可以辅助出现,但不能抢占或替代 `MAOMOMO` 主标识位置。
|
||||
|
|
@ -43,6 +47,10 @@ description: 生成或优化符合 maomomo / 猫MOMO 风格的中文出海金融
|
|||
- 每张最终图片必须来自确认后的图片生成后端:当前 agent 的内置图片生成工具,或用户确认后的 `scripts/maomomo_image_gen.py` API/CLI fallback。不得用 Playwright、HTML/CSS、SVG、Pillow、canvas、本地拼贴或手工文字覆盖冒充最终生成图。例外:用户提供真实银行 / 券商 / 钱包截图且需要上传图片 API 做编辑时,必须先向用户确认实际 API 地址 / baseURL、接口归属和是否允许外发;该 API 可能是用户自有兼容服务,不能默认按公共第三方处理。若未确认、确认不允许或安全策略不允许上传,则先用图片后端生成不含真实截图的空白模板,再在本地把原截图完整嵌入模板;本地步骤只能做排版嵌入、圆角、阴影和尺寸适配,不得改动截图内金额、日期、姓名、账号、交易描述等关键内容,并必须在状态文件和最终回复说明这是“图片后端模板 + 本地嵌入真实截图”的混合流程。
|
||||
- 生成图片按“一张图一个 job / 一次请求 / 一次 QA”推进;通过 QA 后才用状态脚本记录 result 并同步到 `assets/`,不能只生成到 `origin_image/` 后声称完成。运行环境支持子 agent 时,样张通过后可以一图一个子 agent 并发处理;每个 dispatch、结果和 blocker 都必须写入状态文件,不能只靠聊天说明。
|
||||
- 完整交付模式下,不能只在聊天里输出正文;必须生成 Markdown 文件、`assets/` 目录和 ZIP 包,除非用户明确说只要文字、只要大纲、不要图片、不要打包或先不生成文件。
|
||||
- 图片交付完成后必须生成或更新 `final_manifest.json`,最终推送、打包或链接交付只能读取 `final_manifest.json` 或状态文件里明确标记为 final 的 assets;不得把 `draft`、`v2`、旧比例、失败图或未通过 QA 的图一起交付。
|
||||
- 面向 Telegram / 聊天渠道的大文件交付默认改为 GitHub 分批推送:例如 `batch-01-cover`、`batch-02-content-cards`、`batch-03-final-assets`。Telegram 只负责通知进度和给 GitHub 文件路径、commit、release 或下载链接,不承载大 ZIP 或大图片包。
|
||||
- 需要 GitHub 分批交付,或用户提到 GitHub 仓库、专用 KEY、token、PAT、deploy key 时,必须先读 `references/github-delivery.md`,引导配置专用私有交付仓库和最小权限凭据;不得要求用户在聊天里粘贴密钥,不得把 token / 私钥写入 prompt、manifest、状态文件、README、日志或提交记录。
|
||||
- 每张图都必须在状态文件记录:prompt 文件、生成结果、QA 状态、是否进入 `assets/`、是否已推送 GitHub。中断恢复时先读状态文件和 `final_manifest.json`,不要依赖聊天记忆。
|
||||
- 配图文件必须是独立 PNG;不要用一张大拼图代替多张图,不要只给提示词冒充图片文件。
|
||||
- 后续改稿必须更新文件本体;影响图片、来源区、标题、摘要或 ZIP 时同步更新。
|
||||
|
||||
|
|
@ -56,19 +64,19 @@ description: 生成或优化符合 maomomo / 猫MOMO 风格的中文出海金融
|
|||
4. 输出全部图片 prompt 文件和图片任务状态文件。
|
||||
5. 生成并确认一张样张。
|
||||
6. 逐张生成剩余图片并记录 dispatch / result / blocker。
|
||||
7. QA、返修、生成 `speech.md` 或备注稿。
|
||||
8. 打包并交付最终文件。
|
||||
7. QA、返修、生成 `speech.md`、小红书发布文案或备注稿。
|
||||
8. 写入 `final_manifest.json`,按渠道打包或 GitHub 分批推送最终文件。
|
||||
|
||||
不要因为聊天里说“已完成”就标记完成;用实际文件、已读取来源、已生成图片和 ZIP 作为完成证据。
|
||||
不要因为聊天里说“已完成”就标记完成;用实际文件、已读取来源、已生成图片、`final_manifest.json`、ZIP 或 GitHub 批次记录作为完成证据。
|
||||
|
||||
## 默认工作流
|
||||
|
||||
一句话版:读资料 -> 给标题 / 大纲 / 风格让用户确认 -> 写文章 -> 输出图片 prompts 文件让用户改 -> 先出一张图确认 -> 逐张生成剩余图 -> QA -> 打包交付。
|
||||
一句话版:判断模式 -> 读资料 -> 给标题 / 大纲 / 卡片结构 / 风格让用户确认 -> 写文章或小红书文案 -> 输出图片 prompts 文件让用户改 -> 先出一张图确认 -> 逐张生成剩余图 -> QA -> 写 `final_manifest.json` -> 打包或 GitHub 分批交付。
|
||||
|
||||
1. 判断任务模式。
|
||||
- 完整交付、只要大纲、只要正文、只要配图、SEO 优化、改稿更新、小红书发布版。
|
||||
- 完整交付、只要大纲、只要正文、只要配图、SEO 优化、改稿更新、小红书卡片模式。
|
||||
- 判断是否涉及金融 / 活动 / 合规事实核查。
|
||||
- 完整交付或打包任务先读 `references/delivery-rules.md`;需要配图时先读 `references/visual-assets.md`。
|
||||
- 完整交付、打包、GitHub 分批推送或小红书卡片任务先读 `references/delivery-rules.md`;需要配图时先读 `references/visual-assets.md`;需要 GitHub 推送或仓库 / KEY 配置时先读 `references/github-delivery.md`。
|
||||
|
||||
2. 读取源材料并建立事实表。
|
||||
- 先读用户提供的官方页面、PDF、旧文、参考链接、截图或素材,不先动手写最终稿。
|
||||
|
|
@ -83,8 +91,12 @@ description: 生成或优化符合 maomomo / 猫MOMO 风格的中文出海金融
|
|||
- 有必选素材时,必须先确认“素材到章节 / 图位”的映射,再进入风格选择或图片生成。
|
||||
- 若存在多个活动分支、旧版活动、小众资格或来源冲突,先建议主文范围,等用户确认后再写最终稿。
|
||||
- 用户明确要求“直接生成”时,可以继续执行,但所有未确认事实必须标 `【待确认:...】`。
|
||||
- 小红书卡片模式的 `outline.md` 可以简化为卡片结构:图片数量、比例、每张卡片角色、核心文案、话题标签、必选素材映射和分批交付计划。
|
||||
|
||||
4. 确认视觉风格。
|
||||
- 小红书卡片模式必须先确认比例 `3:4` 或 `9:16`,以及视觉方向 `2D 扁平风` 或 `3D 轻拟物风`。
|
||||
- 小红书卡片模式用户没指定视觉方向时,推荐 `2D 扁平风`:清爽、信息卡片、适合教程 / 规则说明,文字更稳;`3D 轻拟物风` 更有质感,适合封面 / 活动感 / 金融产品展示。
|
||||
- 小红书卡片模式一旦确认 2D / 3D,所有 prompt、样张、剩余图片和 final manifest 都必须记录同一 `visual_direction`,不得混用。
|
||||
- 若用户没有指定视觉方向,读 `references/recommended-styles.md`,给 2-3 个 MAOMOMO 配图风格选项并推荐一个。
|
||||
- 用户提供参考图、PPT、PDF 或旧文章风格时,先总结可复用的配色、版式、字体气质、猫咪元素、信息密度和禁用项。
|
||||
- 确认后,整篇文章保持同一视觉系统:稳定配色、猫咪造型、标题区、图标语言、品牌识别和信息密度;不同图位可以变化构图。
|
||||
|
|
@ -123,6 +135,8 @@ description: 生成或优化符合 maomomo / 猫MOMO 风格的中文出海金融
|
|||
├── deck_spec.json
|
||||
├── slide_jobs.json
|
||||
├── slide_run_state.json
|
||||
├── final_manifest.json
|
||||
├── github_batches.json
|
||||
├── outline.md
|
||||
├── article.md
|
||||
├── speech.md
|
||||
|
|
@ -134,11 +148,14 @@ description: 生成或优化符合 maomomo / 猫MOMO 风格的中文出海金融
|
|||
- `deck_spec.json` 记录文章级上下文、确认后的风格、生图后端、样张生成方法 `sample_generation_method`、参考素材映射和图片任务列表。
|
||||
- `prompts/{article_slug}_XX.json` 记录每张图的文件名、用途、放置位置、核心文案、完整 prompt、依赖素材和输出路径。
|
||||
- `slide_jobs.json` 和 `slide_run_state.json` 记录每个图片 job 的 pending / dispatched / recorded / blocked 状态;使用 `scripts/maomomo_job_state.py` 初始化和记录状态。
|
||||
- `final_manifest.json` 只记录通过 QA 且进入 `assets/` 的最终交付文件;`github_batches.json` 记录每批 GitHub 推送的 batch id、文件路径、commit、release 或下载链接。
|
||||
- 小红书卡片项目没有文章正文时,可以省略 `article.md` 和 ZIP,但仍必须保留 `origin_image/`、`assets/`、`prompts/`、`slide_jobs.json`、`slide_run_state.json`、`final_manifest.json` 和 `github_batches.json`。
|
||||
|
||||
8. 出图前整理全部 prompt。
|
||||
- 每张图的文件名、用途、放置位置、核心文案、完整 prompt、alt text、风格、依赖素材和输出路径先写入 `prompts/` 或 manifest 文件。
|
||||
- prompt 中不要写“暖橙金融教程风”“数据仪表盘风”“手绘便签风”等容易被模型照抄的中文风格标签;改写为白底、暖橙强调、信息卡片、猫咪向导、清晰标题等视觉描述。
|
||||
- 每张图的 prompt 必须明确:只允许出现指定业务文案、`MAOMOMO` 和已核对允许出现的品牌 / 支付标识;不得添加副标题、风格标签、prompt 描述、说明文字、额外 slogan 或无关文字。
|
||||
- 小红书 3:4 / 9:16 prompt 必须明确原生竖版重构,并包含 `native portrait composition`、`no squeezed elements`、`no stretched card / logo / text`、`vertical layout redesigned for Xiaohongshu`。
|
||||
- 封面只放最高优先级结论和少量核心数字;复杂计算、全年理论上限、长公式和详细规则放到计算图或正文。
|
||||
- 不要在聊天里输出超长 prompt;告诉用户可直接编辑 prompt 文件。
|
||||
- 如果用户修改 prompt,先同步文件,再生成图片。
|
||||
|
|
@ -160,16 +177,21 @@ description: 生成或优化符合 maomomo / 猫MOMO 风格的中文出海金融
|
|||
|
||||
11. 记录状态、QA 和返修。
|
||||
- 每个图片 job 的 dispatch、结果和 blocker 都用 `scripts/maomomo_job_state.py` 写入 `slide_jobs.json` / `slide_run_state.json`,不能只靠聊天说明完成。
|
||||
- 每张图的状态必须记录 prompt 文件、生成结果、QA 状态、是否进入 `assets/`、是否已推送 GitHub;缺失记录时不得进入最终交付。
|
||||
- 每张图通过前必须检查日期、金额、公式、卡组织 / 支付网络、禁用分支、风格说明文字、伪造截图、乱码和多余文案。
|
||||
- 检查文字清晰度、中文乱码、金额 / 日期 / 规则是否残留旧口径、标题截断、风格一致性、必选素材是否正确、元素是否重叠、是否伪造截图或 Logo。
|
||||
- 小红书 3:4 / 9:16 图额外检查:比例正确、竖版原生构图、元素没有被压扁、卡片 / Logo / 文字没有拉伸、不是横图硬塞进竖版。
|
||||
- 严重问题重新生成该单张;局部问题优先使用已确认后端的编辑能力修复,不得本地手工覆盖关键文字冒充模型输出。
|
||||
|
||||
12. 生成 `speech.md`、组装文章包并最终 QA。
|
||||
12. 生成 `speech.md`、`final_manifest.json`、组装文章包或 GitHub 批次并最终 QA。
|
||||
- `speech.md` 用作每张图的备注 / 讲解稿,标题格式使用 `## Slide N: 标题`,便于和图片顺序映射。
|
||||
- 组装最终文章包时,把 `origin_image/{article_slug}_XX.png` 按顺序同步到 Markdown 引用的 `assets/`,并确保 `article.md`、图片路径、`speech.md`、来源区和 ZIP 都是最新版本。
|
||||
- 最终交付只能读取 `final_manifest.json` 或状态文件中 `qa_status=passed`、`entered_assets=true`、`final=true` 的文件,不扫描整个目录交付。
|
||||
- 需要 GitHub 分批交付时,先按 `references/github-delivery.md` 确认交付仓库、认证方式、目标路径和仓库隐私级别;缺配置时先给用户本机配置步骤并暂停 push。配置就绪后按 `batch-01-cover`、`batch-02-content-cards`、`batch-03-final-assets` 等批次推送;每批推送后记录 GitHub 文件路径、commit、release 或下载链接,并写入 `github_batches.json` / 状态文件。
|
||||
- 完整交付、文件交付或改稿打包前读 `references/delivery-rules.md`。
|
||||
- QA 必须用脚本检查 Markdown 中所有图片路径真实存在,并检查 assets 是否存在、来源区只保留实际使用来源、正文无编辑痕迹、图片无错误日期 / 金额 / 未确认结论、用户要求删除内容不残留、ZIP 内容正确。
|
||||
- 最终回复保持简短:给出项目目录、文章路径、图片目录、ZIP 路径、图片数量、生图后端、状态记录情况、备注写入情况和已知限制。
|
||||
- 小红书卡片模式最终回复固定包含:GitHub 链接、图片数量、风格:2D / 3D、比例:3:4 / 9:16、批次数量、QA 是否完成、已知限制。
|
||||
- 完整文章模式最终回复保持简短:给出项目目录、文章路径、图片目录、ZIP 或 GitHub 链接、图片数量、生图后端、状态记录情况、备注写入情况和已知限制。
|
||||
|
||||
## 模式选择
|
||||
|
||||
|
|
@ -177,7 +199,7 @@ description: 生成或优化符合 maomomo / 猫MOMO 风格的中文出海金融
|
|||
- “只要大纲”“先列结构”:只输出标题备选、大纲、事实缺口、来源清单和图片规划。
|
||||
- “只要文字”“不要图片”“不要打包”“先不要生成文件”:按用户限制输出,不强制创建文件包。
|
||||
- “SEO 优化”“配图”“打包”且用户提供已有 Markdown:读取原文后输出优化版 Markdown、assets 和 ZIP。
|
||||
- “小红书”“4 图看完”“发小红书”:读 `references/style-guide.md` 的小红书规则,并按 9:16 竖图规划。
|
||||
- “小红书”“卡片”“多图”“4 图看完”“发小红书”“3:4”“9:16”:小红书卡片模式;读 `references/style-guide.md` 和 `references/visual-assets.md` 的小红书规则,按 3:4 或 9:16 原生竖版规划,不默认生成完整文章、Markdown 或 ZIP。
|
||||
- 后续说“删掉 X”“合并 3、4”“不要写 Y”“改成 Z”:视为编辑指令,不要把指令原样写进正文。
|
||||
|
||||
## 改稿协作规则
|
||||
|
|
@ -203,6 +225,16 @@ description: 生成或优化符合 maomomo / 猫MOMO 风格的中文出海金融
|
|||
- 金融、银行、券商、数字货币、汇款、税务或合规内容包含保守风险提示。
|
||||
- 用户要求删除或收敛的分支,不残留在标题、摘要、正文、图片 alt、配图清单、来源区或 ZIP。
|
||||
|
||||
小红书卡片模式必须满足:
|
||||
|
||||
- 每张最终图是独立 PNG,比例为用户确认的 `3:4` 或 `9:16`。
|
||||
- 已确认 `2D 扁平风` 或 `3D 轻拟物风`,且全组一致。
|
||||
- prompt、状态文件和 QA 记录包含原生竖版构图、防压扁和防拉伸约束。
|
||||
- `final_manifest.json` 只包含通过 QA 且进入 `assets/` 的最终图片。
|
||||
- GitHub 分批推送记录已写入状态文件或 `github_batches.json`;Telegram 只发送进度和链接。
|
||||
- GitHub 交付仓库和专用 KEY / token / deploy key 已按 `references/github-delivery.md` 配置或明确记录为阻塞项。
|
||||
- 最终回复包含 GitHub 链接、图片数量、风格、比例、批次数量、QA 是否完成和已知限制。
|
||||
|
||||
如果无法完成,最终回复必须说明:阻塞阶段、缺失材料或失败工具、已完成文件路径、未完成项和下一步需要什么。
|
||||
|
||||
## Reference Map
|
||||
|
|
@ -212,5 +244,6 @@ description: 生成或优化符合 maomomo / 猫MOMO 风格的中文出海金融
|
|||
- `references/visual-assets.md`:配图类型、猫咪视觉、文件命名、Markdown 插图、金融卡面核对、可见文字限制、禁止伪造截图和图片 QA。
|
||||
- `references/recommended-styles.md`:推荐配图风格、适用场景、推荐话术和提示词片段。
|
||||
- `references/image-styles/*.md`:具体出图风格 brief,借鉴 `codex-ppt-skill` 风格库结构并适配 MAOMOMO 文章配图。
|
||||
- `references/image-generation.md`:图片生成后端选择、`scripts/maomomo_image_gen.py` 用法、`scripts/maomomo_job_state.py` 状态记录、manifest 和故障处理。
|
||||
- `references/delivery-rules.md`:完整交付、ZIP、更新打包、附件策略和最终检查清单。
|
||||
- `references/image-generation.md`:图片生成后端选择、`scripts/maomomo_image_gen.py` 用法、`scripts/maomomo_job_state.py` 状态记录、final manifest、GitHub 批次记录和故障处理。
|
||||
- `references/github-delivery.md`:GitHub 交付仓库、专用 KEY / token / deploy key、环境变量、隐私边界和分批推送前置检查。
|
||||
- `references/delivery-rules.md`:完整交付、ZIP、GitHub 分批推送、更新打包、附件策略和最终检查清单。
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
interface:
|
||||
display_name: "MAOMOMO 文章生成器"
|
||||
short_description: "分阶段确认后生成 MAOMOMO 文章、配图和 ZIP 发布包"
|
||||
default_prompt: "使用 $maomomo-article-writer 生成或优化一篇 MAOMOMO 风格的中文出海金融实操文章。请先核查来源和事实表,再确认标题、口径、大纲、素材映射、配图风格和生图后端;写文章后先输出图片 prompts 文件,只生成一张样张确认,再逐张生成剩余图片,最后交付 Markdown、assets 独立配图目录和 ZIP 包。"
|
||||
short_description: "分阶段确认后生成 MAOMOMO 文章、配图、小红书卡片和 GitHub 交付包"
|
||||
default_prompt: "使用 $maomomo-article-writer 生成或优化一篇 MAOMOMO 风格的中文出海金融实操文章或小红书卡片。请先核查来源和事实表,再确认标题、口径、大纲或卡片结构、素材映射、2D/3D 视觉方向、比例和生图后端;如需 GitHub 交付,先引导配置专用私有仓库和最小权限 KEY / token / deploy key;先输出图片 prompts 文件,只生成一张样张确认,再逐张生成剩余图片,最后用 final_manifest.json 控制最终 assets,并按需要交付 Markdown、ZIP 或 GitHub 分批链接。"
|
||||
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# MAOMOMO 完整交付规则
|
||||
|
||||
本文件用于完整文章、配图、发布包、打包、一键下载和后续更新任务。只要用户没有明确说“只要文字”“不要图片”“不要打包”“先不要生成文件”“先只要大纲”,默认按完整交付模式执行。
|
||||
本文件用于完整文章、配图、发布包、打包、一键下载、GitHub 分批推送和后续更新任务。只要用户没有明确说“只要文字”“不要图片”“不要打包”“先不要生成文件”“先只要大纲”,默认按完整交付模式执行。用户提到“小红书”“卡片”“多图”“3:4”“9:16”时,默认进入小红书卡片模式,不默认生成完整文章、Markdown 或 ZIP。
|
||||
|
||||
完整交付模式指“最终交付物必须完整”,不代表可以跳过确认一次性全量生成。执行时必须遵守 `SKILL.md` 的阶段门禁:先读资料和事实表,再确认标题 / 口径 / 大纲 / 素材映射 / 配图风格 / 生图后端,随后写文章、整理 prompts、先出一张样张,样张确认后再逐张生成剩余图片。
|
||||
|
||||
|
|
@ -47,16 +47,48 @@ article_package.zip
|
|||
|
||||
## 多渠道交付策略
|
||||
|
||||
完整交付默认生成 Markdown、assets 和 ZIP,但最终发送方式按渠道和用户要求调整。
|
||||
完整文章交付默认生成 Markdown、assets 和 ZIP;小红书卡片和大图片交付默认生成 `assets/`、`final_manifest.json` 和 GitHub 分批链接。最终发送方式按渠道和用户要求调整。
|
||||
|
||||
- 本地 / Web:优先给 Markdown + ZIP;如用户要图片,也附独立图片。
|
||||
- Telegram / 聊天:ZIP 可能失败,优先发送 Markdown + 多张图片独立附件;ZIP 作为可选补充。
|
||||
- 本地 / Web:完整文章可给 Markdown + ZIP;小红书卡片给 `assets/`、`final_manifest.json` 和 GitHub 链接。
|
||||
- GitHub:图片较多、文件较大、Telegram 可能失败或用户要求最终交付时,先读 `references/github-delivery.md`,确认交付仓库、专用 KEY / token / deploy key、仓库隐私级别和目标路径;配置就绪后按批次推送,例如 `batch-01-cover`、`batch-02-content-cards`、`batch-03-final-assets`。每批推送后记录 GitHub 文件路径、commit、release 或下载链接。
|
||||
- Telegram / 聊天:只负责通知进度和给 GitHub 链接;不要依赖 Telegram 直接承载 ZIP 或大图片包。少量小文件附件只能作为补充,不作为唯一交付证据。
|
||||
- Email:按用户要求选择 ZIP 或独立附件。
|
||||
- 用户说“打包发我 email”:发送 ZIP。
|
||||
- 用户说“不打包”“分多个附件”:发送 Markdown 和图片作为多个独立附件,不再附 ZIP。
|
||||
- 若附件发送失败,不要反复重复发送同一批附件;改用更稳定的渠道或分批发送,并说明只保留最后版本。
|
||||
- 发送前确认附件对应的是最后确认版,不要把旧图、旧 Markdown 或临时文件发出。
|
||||
|
||||
## 小红书卡片交付模式
|
||||
|
||||
触发词包括“小红书”“卡片”“多图”“4 图看完”“发小红书”“3:4”“9:16”。
|
||||
|
||||
执行规则:
|
||||
|
||||
1. 不默认走完整文章 + Markdown + ZIP;除非用户明确要求,只交付小红书标题、正文、话题标签和多张独立 PNG。
|
||||
2. 出图前确认比例 `3:4` 或 `9:16`,确认视觉方向 `2D 扁平风` 或 `3D 轻拟物风`。用户没指定时推荐 `2D 扁平风`。
|
||||
3. 每张图 prompt 必须包含原生竖版防压扁规则:`native portrait composition`、`no squeezed elements`、`no stretched card / logo / text`、`vertical layout redesigned for Xiaohongshu`。
|
||||
4. 每张图按一个 job / 一次请求 / 一次 QA 推进,状态文件记录 prompt 文件、生成结果、QA 状态、是否进入 `assets/`、是否已推送 GitHub。
|
||||
5. QA 通过后生成 `final_manifest.json`,只包含最终图;推送或打包只能读取该 manifest 或状态文件里标记为 final 的 assets。
|
||||
6. GitHub 分批推送前必须按 `references/github-delivery.md` 完成或确认仓库和专用凭据配置。缺少配置时先输出本机配置步骤并暂停 push,不生成假链接。
|
||||
7. GitHub 分批推送建议:
|
||||
- `batch-01-cover`:封面图和封面 prompt。
|
||||
- `batch-02-content-cards`:内容卡、流程卡、避坑卡。
|
||||
- `batch-03-final-assets`:`final_manifest.json`、全部 final assets、状态文件。
|
||||
8. 每批推送后立即回报 GitHub 文件路径、commit、release 或下载链接,并写入 `github_batches.json` 或状态文件。
|
||||
9. 最终回复固定包含 GitHub 链接、图片数量、风格:2D / 3D、比例:3:4 / 9:16、批次数量、QA 是否完成、已知限制。
|
||||
|
||||
## GitHub 交付配置门禁
|
||||
|
||||
GitHub 交付前必须先完成以下检查:
|
||||
|
||||
- 已读取 `references/github-delivery.md`。
|
||||
- 已确认目标仓库,例如 `OWNER/maomomo-delivery`。
|
||||
- 仓库默认是私有;公开仓库必须经用户明确确认。
|
||||
- 已确认认证方式:`gh auth login`、`GH_TOKEN` fine-grained PAT,或 SSH deploy key。
|
||||
- 凭据必须是专用且最小权限:fine-grained PAT 只给交付仓库 `Contents: Read and write`;deploy key 只授权单仓库 write access。
|
||||
- 不要求用户在聊天里粘贴 token 或私钥;不把密钥写入项目文件、manifest、状态文件、日志或 commit。
|
||||
- `github_batches.json` 只记录 batch、文件路径、commit、release / url 和备注。
|
||||
|
||||
## 配图执行规则
|
||||
|
||||
具体视觉风格、图片清单、文件命名、Markdown 插图和图片 QA 规则见 `references/visual-assets.md`。本节只规定完整交付时的执行边界。
|
||||
|
|
@ -74,6 +106,7 @@ article_package.zip
|
|||
- 第三方 Logo 必须尺寸克制、位置辅助,不能抢占、替代或压过 `MAOMOMO` 主标识。
|
||||
- 不得伪造真实 App 截图。
|
||||
- prompt 中的视觉风格只能写成后台画面描述,不要写容易被模型照抄的中文风格标签;可见文字只允许出现指定业务文案、`MAOMOMO` 和已核对允许出现的品牌 / 支付标识。
|
||||
- 小红书 3:4 / 9:16 图片必须原生竖版重新构图,不能把横版设计压进竖图;prompt 必须包含防压扁和防拉伸英文约束。
|
||||
- 生成图应明确是 MAOMOMO 示意图 / 信息图,不伪装成真实截图或官方页面。
|
||||
- 生成后的原始最终图先保存到 `origin_image/`,通过 QA 后同步到 `assets/`,并插入 Markdown。
|
||||
- 港币金额在发布稿、图片文案、prompt、manifest 和 `deck_spec.json` 中统一写 `HKD`,来源原文抽取文件除外。
|
||||
|
|
@ -97,7 +130,9 @@ article_package.zip
|
|||
- 只输出配图提示词,不生成图片文件。
|
||||
- 只生成图片,不插入 Markdown。
|
||||
- 只生成一张总图,不生成多张独立配图。
|
||||
- 只给 assets,不打 ZIP。
|
||||
- 完整文章模式只给 assets,不打 ZIP。
|
||||
- 小红书卡片只扫描目录交付,未生成 `final_manifest.json`,导致草稿、失败图、旧比例图混入最终包。
|
||||
- Telegram 发送失败后仍反复传大 ZIP,而不是改用 GitHub 分批链接。
|
||||
- 只给一段新增内容,不输出更新后的完整文章。
|
||||
- 只给旧文件链接,没有确认文件内容已更新。
|
||||
- 修改了正文,但没有同步更新标题、摘要、配图清单、来源区和 ZIP 包。
|
||||
|
|
@ -145,6 +180,9 @@ article_package.zip
|
|||
- `prompts/` 中每张图的 prompt 文件已保存,且与最终图片数量和顺序一致。
|
||||
- 一张样张已确认,后续图片继承同一生图后端和视觉系统。
|
||||
- `slide_jobs.json` / `slide_run_state.json` 已记录图片任务状态;如缺少记录,最终回复必须说明原因。
|
||||
- 每张图的状态记录包含 prompt 文件、生成结果、QA 状态、是否进入 `assets/`、是否已推送 GitHub。
|
||||
- `final_manifest.json` 已生成,并且最终交付只读取 manifest 中列出的 final assets。
|
||||
- 需要 GitHub 交付时,已确认 `references/github-delivery.md` 中的仓库、专用凭据、隐私级别和目标路径;缺失时最终回复说明配置阻塞项。
|
||||
- `origin_image/` 中最终原始图片存在。
|
||||
- `assets/` 目录已生成。
|
||||
- 已运行 `uv run python scripts/maomomo_check_markdown_assets.py article/article.md` 或等效脚本,确认所有 Markdown 图片路径都能对应到真实图片文件。
|
||||
|
|
@ -158,7 +196,7 @@ article_package.zip
|
|||
- 文末来源区只包含实际使用的来源。
|
||||
- 正文没有 `contentReference`、`oaicite`、调试标记或工具残留。
|
||||
- 用户要求删除的分支,标题、正文、配图清单和来源区都已删除干净。
|
||||
- ZIP 包已创建。
|
||||
- 完整文章模式下 ZIP 包已创建;小红书卡片模式下 `final_manifest.json` 和 GitHub 批次记录已创建。
|
||||
- 用户最后确认的标题是否已同步到 frontmatter 和 H1。
|
||||
- 用户要求删除的词是否只删除指定词,未误删整条信息。
|
||||
- 正文是否残留编辑指令或模型解释。
|
||||
|
|
@ -166,8 +204,9 @@ article_package.zip
|
|||
- 用户提供的明确实测结论是否写成确定语气,未被改软成“可能 / 疑似 / 大概”。
|
||||
- 用户提供的“以往惯例 / 过往尿性 / 过往经验”是否写成“大概率 / 按过往案例判断”的强概率语气,并保留合理边界。
|
||||
- TLDR 是否过长,是否适合当前平台。
|
||||
- 小红书图是否为 9:16 竖版,是否每张都有 MAOMOMO 标识。
|
||||
- 小红书图是否为用户确认的 3:4 或 9:16,是否每张都有 MAOMOMO 标识,是否为原生竖版重构,是否没有压扁或拉伸。
|
||||
- 小红书图是否全组保持同一 2D / 3D 视觉方向。
|
||||
- 图片是否匹配最终文章口径,未残留旧规则、旧金额、旧标题。
|
||||
- 邮件/聊天附件是否按用户要求选择 ZIP 或多个独立附件。
|
||||
- 邮件/聊天附件是否按用户要求选择 ZIP、多个独立附件或 GitHub 分批链接;Telegram 是否只承载通知和链接。
|
||||
- 若已发送过旧版本,最终回复要明确这是最后版本,避免重复发同一批图片。
|
||||
- 最终回复包含 Markdown 下载链接和 ZIP 下载链接。
|
||||
- 完整文章最终回复包含 Markdown 下载链接和 ZIP 或 GitHub 链接;小红书卡片最终回复包含 GitHub 链接、图片数量、风格、比例、批次数量、QA 是否完成和已知限制。
|
||||
|
|
|
|||
|
|
@ -0,0 +1,138 @@
|
|||
# GitHub 交付配置
|
||||
|
||||
本文件用于 GitHub 分批交付前的仓库和专用凭据配置。只要任务需要 GitHub push、release、下载链接,或用户提到 GitHub 仓库、专用 KEY、token、PAT、deploy key,先读本文件。
|
||||
|
||||
## 目标
|
||||
|
||||
- 使用专门的交付仓库,不和源码仓库混放。
|
||||
- 默认使用私有仓库,除非用户明确要求公开交付。
|
||||
- 使用专用、最小权限凭据;不要复用高权限个人 token。
|
||||
- 不在聊天、prompt、manifest、状态文件、README、日志或提交记录里暴露完整 token / 私钥。
|
||||
|
||||
## 推荐配置
|
||||
|
||||
推荐环境变量:
|
||||
|
||||
```bash
|
||||
export MAOMOMO_GITHUB_REPO="OWNER/maomomo-delivery"
|
||||
export MAOMOMO_GITHUB_BRANCH="main"
|
||||
export MAOMOMO_GITHUB_BASE_PATH="deliveries"
|
||||
```
|
||||
|
||||
认证方式任选其一:
|
||||
|
||||
1. GitHub CLI 登录,适合本机交互使用:
|
||||
|
||||
```bash
|
||||
gh auth login --web --git-protocol https
|
||||
gh auth status
|
||||
```
|
||||
|
||||
2. Fine-grained PAT,适合脚本或无头环境:
|
||||
|
||||
- Repository access:只选交付仓库。
|
||||
- Repository permissions:只给 `Contents: Read and write`。
|
||||
- 过期时间:建议 30-90 天。
|
||||
- 本机设置为环境变量,不要发到聊天里:
|
||||
|
||||
```bash
|
||||
export GH_TOKEN="只在本机 shell 中设置,不写入项目文件"
|
||||
gh auth status
|
||||
```
|
||||
|
||||
3. SSH deploy key,适合只给单仓库写权限:
|
||||
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -f "$HOME/.ssh/maomomo_delivery_ed25519" -C "maomomo-delivery"
|
||||
```
|
||||
|
||||
把 `.pub` 公钥加入 GitHub 仓库 Settings -> Deploy keys,并勾选 write access。私钥只留本机,推送时使用:
|
||||
|
||||
```bash
|
||||
export GIT_SSH_COMMAND="ssh -i $HOME/.ssh/maomomo_delivery_ed25519 -o IdentitiesOnly=yes"
|
||||
```
|
||||
|
||||
## 首次仓库准备
|
||||
|
||||
如果用户还没有交付仓库,先引导其创建或确认仓库名。不要擅自创建公开仓库。
|
||||
|
||||
```bash
|
||||
gh repo create "$MAOMOMO_GITHUB_REPO" --private --clone=false
|
||||
```
|
||||
|
||||
检查仓库:
|
||||
|
||||
```bash
|
||||
gh repo view "$MAOMOMO_GITHUB_REPO" --json nameWithOwner,visibility,defaultBranchRef
|
||||
```
|
||||
|
||||
如果 `visibility` 不是 `PRIVATE`,先提醒用户可能公开图片、prompt、状态文件和活动信息;除非用户明确确认,否则不要继续推送。
|
||||
|
||||
## 本地工作目录
|
||||
|
||||
GitHub 交付工作目录默认放在 `$HOME/dev` 下,避免散落到桌面、下载目录或系统目录:
|
||||
|
||||
```bash
|
||||
mkdir -p "$HOME/dev/maomomo-delivery-work"
|
||||
cd "$HOME/dev/maomomo-delivery-work"
|
||||
```
|
||||
|
||||
如果仓库尚未 clone:
|
||||
|
||||
```bash
|
||||
gh repo clone "$MAOMOMO_GITHUB_REPO" repo
|
||||
```
|
||||
|
||||
目标路径建议:
|
||||
|
||||
```text
|
||||
deliveries/{project_slug}/
|
||||
├── batch-01-cover/
|
||||
├── batch-02-content-cards/
|
||||
├── batch-03-final-assets/
|
||||
├── final_manifest.json
|
||||
├── github_batches.json
|
||||
└── slide_run_state.json
|
||||
```
|
||||
|
||||
## 推送前检查
|
||||
|
||||
推送前必须确认:
|
||||
|
||||
- `MAOMOMO_GITHUB_REPO` 已设置,或用户已明确给出目标仓库。
|
||||
- 已通过 `gh auth status`,或 SSH deploy key 已能写入目标仓库。
|
||||
- 仓库默认为私有;公开仓库必须经用户明确确认。
|
||||
- `final_manifest.json` 已生成,最终文件只从 manifest 或状态文件里的 final assets 读取。
|
||||
- 本批文件不包含 token、私钥、账号、真实个人信息或未确认敏感素材。
|
||||
- `github_batches.json` 只记录 batch、路径、commit、release / url,不记录任何密钥。
|
||||
|
||||
## 分批推送流程
|
||||
|
||||
每批只复制本批需要交付的文件,不扫描整个项目目录。提交信息优先中文:
|
||||
|
||||
```bash
|
||||
git add deliveries/{project_slug}/batch-01-cover deliveries/{project_slug}/github_batches.json
|
||||
git commit -m "交付:{project_slug} batch-01-cover"
|
||||
git push origin "$MAOMOMO_GITHUB_BRANCH"
|
||||
```
|
||||
|
||||
推送后用状态脚本记录:
|
||||
|
||||
```bash
|
||||
uv run python scripts/maomomo_job_state.py github-batch article \
|
||||
--batch batch-01-cover \
|
||||
--commit "<commit sha>" \
|
||||
--url "https://github.com/OWNER/REPO/commit/<commit sha>" \
|
||||
--paths assets/example-01-cover.png prompts/example_01.json final_manifest.json
|
||||
```
|
||||
|
||||
每批推送后回复用户:GitHub 文件路径、commit、release 或下载链接,并说明下一批状态。
|
||||
|
||||
## 阻塞处理
|
||||
|
||||
如果缺少仓库或凭据,不要继续生成假链接,也不要要求用户把 token 粘贴到聊天里。回复应包含:
|
||||
|
||||
- 当前阻塞:缺少交付仓库、未登录 GitHub CLI、token 权限不足、deploy key 未授权等。
|
||||
- 本机配置命令。
|
||||
- 需要用户确认的仓库名或认证方式。
|
||||
- 已完成的本地文件路径和下一步。
|
||||
|
|
@ -102,6 +102,8 @@ manifest 示例:
|
|||
"core_text": "先报名,再看门槛和封顶",
|
||||
"alt_text": "MAOMOMO 汇丰 Mastercard 支付宝返现活动封面图",
|
||||
"style": "warm-fintech-guide",
|
||||
"visual_direction": "2D 扁平风",
|
||||
"delivery_batch": "batch-01-cover",
|
||||
"allowed_brand_marks": ["HSBC", "Mastercard", "支付宝"],
|
||||
"brand_mark_sources": [
|
||||
{
|
||||
|
|
@ -143,6 +145,8 @@ uv run python scripts/maomomo_image_gen.py batch \
|
|||
- 发布用 Markdown 默认引用 `assets/`,因此如果 manifest 输出到 `origin_image/`,必须在 QA 后复制到对应 `assets/` 路径。
|
||||
- 金融活动 manifest 中涉及信用卡、支付卡、支付网络或机构 Logo 时,必须记录 `reference_assets`、`payment_network`、`allowed_brand_marks`、`brand_mark_sources` 和 `card_art_rule`,并在 QA 中核对卡组织和第三方 Logo 没有画错,也没有抢 MAOMOMO 主标识位置。用户未提供 Logo / 卡面素材时,先尽力查找官方或可信来源并保存到 `sources/`;无法核对时使用通用符号,不要凭记忆画真实 Logo。
|
||||
- manifest、prompt、`deck_spec.json` 和发布稿中的港币金额统一使用 `HKD`,来源原文抽取文件除外。
|
||||
- 小红书卡片 manifest 必须记录 `aspect_ratio`、`visual_direction`、`delivery_batch` 和 `portrait_composition_rules`;prompt 必须包含 `native portrait composition`、`no squeezed elements`、`no stretched card / logo / text`、`vertical layout redesigned for Xiaohongshu`。
|
||||
- 小红书卡片默认不生成完整文章、Markdown 或 ZIP;最终文件清单以 `final_manifest.json` 为准。
|
||||
|
||||
## 内置风格名
|
||||
|
||||
|
|
@ -194,6 +198,8 @@ uv run python scripts/maomomo_image_gen.py styles
|
|||
- 发布图,例如 `assets/hsbc-mastercard-alipay-campaign-01-cover.png`
|
||||
- 状态:`pending`、`dispatched`、`recorded`、`blocked`
|
||||
- 生图后端、agent id、QA note、失败原因
|
||||
- 小红书卡片字段:`aspect_ratio`、`visual_direction`、`delivery_batch`
|
||||
- 最终交付字段:`qa_status`、`entered_assets`、`final`、`github_pushed`、`github_batch`
|
||||
|
||||
使用 `scripts/maomomo_job_state.py` 更新状态,不要手工改 JSON 后声称完成。
|
||||
|
||||
|
|
@ -240,3 +246,25 @@ uv run python scripts/maomomo_job_state.py blocker article \
|
|||
```
|
||||
|
||||
如果状态脚本失败,最终报告必须说明原因,并附上状态文件当前路径和未完成 job。
|
||||
|
||||
生成最终 manifest:
|
||||
|
||||
```bash
|
||||
uv run python scripts/maomomo_job_state.py final-manifest article
|
||||
```
|
||||
|
||||
`final_manifest.json` 只写入状态为 `recorded`、QA 已通过、且 `assets/` 文件真实存在的图片。最终推送、打包或给链接时只能读取该文件,不能扫描整个目录。
|
||||
|
||||
记录 GitHub 批次:
|
||||
|
||||
运行前必须先按 `references/github-delivery.md` 完成交付仓库和专用凭据配置;`github-batch` 只记录已经真实推送后的批次结果,不负责创建仓库、保存密钥或生成假链接。
|
||||
|
||||
```bash
|
||||
uv run python scripts/maomomo_job_state.py github-batch article \
|
||||
--batch batch-01-cover \
|
||||
--commit "<commit sha>" \
|
||||
--url "https://github.com/org/repo/commit/<commit sha>" \
|
||||
--paths assets/example-01-cover.png prompts/example_01.json
|
||||
```
|
||||
|
||||
每批推送后都要写入 batch 记录。状态文件里的单图记录会同步标记 `github_pushed=true`、`github_batch=batch-xx`;最终回复从 `github_batches.json` 或状态文件读取批次数量和链接。
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
- 小红书发布版
|
||||
- 4 图看完
|
||||
- 多图卡片 / 3:4 / 9:16
|
||||
- 手机端快速理解的活动 / 避坑 / 教程内容
|
||||
|
||||
## MAOMOMO 出图 Brief
|
||||
|
|
@ -11,11 +12,11 @@
|
|||
```json
|
||||
{
|
||||
"style_name": "xiaohongshu-vertical",
|
||||
"visual_direction": "vertical mobile-first Chinese finance guide card, big readable text, series layout",
|
||||
"visual_direction": "2D flat infographic card by default, optional 3D soft neumorphic direction only after user confirmation, vertical mobile-first Chinese finance guide card, big readable text, series layout",
|
||||
"canvas": {
|
||||
"aspect_ratio": "9:16",
|
||||
"aspect_ratio": "3:4 or 9:16, confirm before generation",
|
||||
"background": "warm white or light orange",
|
||||
"composition": "large hook title, 2-4 key blocks, cat watermark or small mascot",
|
||||
"composition": "native portrait composition, large hook title, 2-4 key blocks, cat watermark or small mascot, vertical layout redesigned for Xiaohongshu",
|
||||
"density": "low, mobile readable"
|
||||
},
|
||||
"color_palette": {
|
||||
|
|
@ -36,6 +37,9 @@
|
|||
],
|
||||
"avoid": [
|
||||
"reuse of horizontal article image",
|
||||
"squeezed elements",
|
||||
"stretched card / logo / text",
|
||||
"mixing 2D and 3D visual directions in one image set",
|
||||
"long source paragraph",
|
||||
"tiny screenshot-like UI",
|
||||
"exaggerated earning promise"
|
||||
|
|
@ -46,5 +50,5 @@
|
|||
## Prompt 片段
|
||||
|
||||
```text
|
||||
9:16 竖版,大字少字,手机端可读,暖橙白底,白橘猫水印,适合 4 图系列,包含 MAOMOMO 标识。可见文字只允许出现指定业务文案、MAOMOMO 和已核对允许出现的品牌 / 支付标识。
|
||||
3:4 或 9:16 原生竖版,native portrait composition,vertical layout redesigned for Xiaohongshu,大字少字,手机端可读,暖橙白底,白橘猫水印,适合多图系列,包含 MAOMOMO 标识。no squeezed elements,no stretched card / logo / text。可见文字只允许出现指定业务文案、MAOMOMO 和已核对允许出现的品牌 / 支付标识。
|
||||
```
|
||||
|
|
|
|||
|
|
@ -187,20 +187,23 @@
|
|||
推荐语:
|
||||
|
||||
```text
|
||||
我建议用 xiaohongshu-vertical,因为用户要发小红书,应该重新做 9:16 竖图,而不是复用站内横版图。
|
||||
我建议用 xiaohongshu-vertical,并默认选 2D 扁平风,因为用户要发小红书,应该重新做 3:4 或 9:16 原生竖图,而不是复用站内横版图;2D 信息卡片更清爽,中文文字也更稳。
|
||||
```
|
||||
|
||||
视觉要点:
|
||||
|
||||
- 9:16 竖版,手机端可读。
|
||||
- 3:4 或 9:16 竖版,手机端可读。
|
||||
- 出图前先确认 `2D 扁平风` 或 `3D 轻拟物风`;默认推荐 2D,3D 适合封面、活动感和金融产品展示。
|
||||
- 全组保持同一 `visual_direction`,不得中途混用。
|
||||
- 大字少字,标题钩子强。
|
||||
- 4 图系列统一:封面、核心拆解、操作流程、避坑总结。
|
||||
- 每张图都有 MAOMOMO 标识或猫咪水印。
|
||||
- 原生竖版重新构图,禁止横版硬塞;元素、卡片、Logo 和文字不能压扁或拉伸。
|
||||
|
||||
提示词片段:
|
||||
|
||||
```text
|
||||
9:16 竖版,手机端可读,大标题,少量关键数字,暖橙白底,白橘猫水印,适合 4 图看完的中文金融攻略,包含 MAOMOMO 标识。可见文字只允许出现指定业务文案、MAOMOMO 和已核对允许出现的品牌 / 支付标识。
|
||||
3:4 或 9:16 原生竖版,native portrait composition,vertical layout redesigned for Xiaohongshu,手机端可读,大标题,少量关键数字,暖橙白底,白橘猫水印,适合多图系列的中文金融攻略,包含 MAOMOMO 标识。no squeezed elements,no stretched card / logo / text。可见文字只允许出现指定业务文案、MAOMOMO 和已核对允许出现的品牌 / 支付标识。
|
||||
```
|
||||
|
||||
## 风格选择输出格式
|
||||
|
|
@ -214,7 +217,7 @@ A. warm-fintech-guide(推荐):【适合原因】
|
|||
B. data-card-dashboard:【适合原因】
|
||||
C. handdrawn-note:【适合原因】
|
||||
|
||||
你选哪个?也可以指定更偏简洁、数据感、手绘感或小红书感。
|
||||
你选哪个?如果是小红书卡片,也请确认用 2D 扁平风还是 3D 轻拟物风;没指定我会默认用 2D。
|
||||
```
|
||||
|
||||
用户选择后,把风格名写入图片清单的 `风格` 字段或 manifest 的 `style` 字段。
|
||||
|
|
|
|||
|
|
@ -176,18 +176,21 @@ MAOMOMO 是偏实操的出海经验平台。公开站点标语是:“打破信
|
|||
- 核心结论可以放在引用块里。
|
||||
- 结尾提醒政策变化风险,例如“直至另行通知”“随时可能取消”。
|
||||
|
||||
### 6. 小红书发布版 / 4 图看完
|
||||
### 6. 小红书卡片模式 / 多图发布
|
||||
|
||||
用户说“小红书”“发小红书”“4图看完”“超短文字”“20字内标题”时,进入小红书模式。
|
||||
用户说“小红书”“卡片”“多图”“发小红书”“4图看完”“3:4”“9:16”“超短文字”“20字内标题”时,进入小红书卡片模式。
|
||||
|
||||
小红书卡片模式是独立交付模式,不默认走完整文章 + Markdown + ZIP 流程。除非用户明确要求文章或打包,否则重点交付多张统一风格的独立 PNG,以及可复制的小红书标题、正文和话题标签。
|
||||
|
||||
交付物:
|
||||
|
||||
- 20 字内标题。
|
||||
- 超短正文,适合直接复制发布。
|
||||
- 3-6 个话题标签。
|
||||
- 4 张 9:16 竖版 PNG 图,不复用文章横版图。
|
||||
- 多张 3:4 或 9:16 竖版 PNG 图,默认 4 张;不复用文章横版图。
|
||||
- 每张图加入 MAOMOMO logo / 猫咪水印。
|
||||
- 如果用户要求 email,按用户要求打包或多附件发送。
|
||||
- `final_manifest.json`,只列通过 QA 且进入 `assets/` 的最终图片。
|
||||
- GitHub 分批交付链接;Telegram / 聊天只通知进度和链接,不承载大 ZIP 或大图包。
|
||||
|
||||
文字规则:
|
||||
|
||||
|
|
@ -205,12 +208,27 @@ MAOMOMO 是偏实操的出海经验平台。公开站点标语是:“打破信
|
|||
|
||||
视觉规则:
|
||||
|
||||
- 纵向 9:16,手机端可读,大字少字。
|
||||
- 出图前必须先确认比例:`3:4` 或 `9:16`。
|
||||
- 出图前必须先确认视觉方向:`2D 扁平风` 或 `3D 轻拟物风`。
|
||||
- 用户没指定时,默认推荐 `2D 扁平风`:清爽、信息卡片、适合教程 / 规则说明,中文文字更稳。
|
||||
- `3D 轻拟物风` 更适合封面、活动感、金融产品展示;一旦确认,整组不能和 2D 混用。
|
||||
- 纵向原生构图,手机端可读,大字少字。
|
||||
- 每张图独立,不要拼图。
|
||||
- 每张图有 MAOMOMO 标识。
|
||||
- 文章横图不能直接当小红书图;需要重新设计。
|
||||
- 禁止把横版设计硬塞进 3:4 或 9:16;prompt 必须包含 `native portrait composition`、`no squeezed elements`、`no stretched card / logo / text`、`vertical layout redesigned for Xiaohongshu`。
|
||||
- 如果用户提供卡片、截图或 Logo 参考,只做原创示意,不复制敏感信息,不伪造真实 App 页面。
|
||||
|
||||
最终回复固定包含:
|
||||
|
||||
- GitHub 链接。
|
||||
- 图片数量。
|
||||
- 风格:2D / 3D。
|
||||
- 比例:3:4 / 9:16。
|
||||
- 批次数量。
|
||||
- QA 是否完成。
|
||||
- 已知限制。
|
||||
|
||||
### 5. 避坑经验
|
||||
|
||||
用于“不要浪费时间试了”、DCC、支付失败、转账姓名顺序问题、线下网点提醒等。
|
||||
|
|
|
|||
|
|
@ -92,13 +92,20 @@ MAOMOMO 暖橙金融教程风,画出一张手绘便签风仪表盘图。
|
|||
|
||||
如果用户没有指定视觉方向,生成图片前先读 `references/recommended-styles.md`,给 2-3 个可选风格,并推荐一个。确认后,整篇文章的配图保持同一套视觉身份:稳定的配色、猫咪造型、标题区、图标语言和信息密度;不同图片可以根据用途变化构图。
|
||||
|
||||
小红书卡片模式先确认两件事:
|
||||
|
||||
- 比例:`3:4` 或 `9:16`。
|
||||
- 视觉方向:`2D 扁平风` 或 `3D 轻拟物风`。用户没指定时,推荐 `2D 扁平风`,因为信息卡片更清爽、教程 / 规则说明更稳,也更不容易出现中文文字翻车;`3D 轻拟物风` 更适合封面、活动感和金融产品展示。
|
||||
|
||||
小红书卡片一旦确认 `2D` 或 `3D`,整组图片必须继承同一个 `visual_direction`,不得中途混用。
|
||||
|
||||
默认推荐逻辑:
|
||||
|
||||
- 活动 / 返现 / 港卡攻略:优先 `warm-fintech-guide`。
|
||||
- 规则、门槛、费用、返现计算和产品对比:优先 `data-card-dashboard`。
|
||||
- SEO 长文、经验整理、品牌感更强的文章:优先 `clean-editorial`。
|
||||
- 保姆式教程、避坑经验和轻量操作步骤:优先 `handdrawn-note`。
|
||||
- 小红书 / 4 图看完:必须用 `xiaohongshu-vertical`,并生成 9:16 竖图。
|
||||
- 小红书 / 4 图看完 / 多图卡片:必须用 `xiaohongshu-vertical`,并按用户确认生成 3:4 或 9:16 竖图。
|
||||
|
||||
可选风格:
|
||||
|
||||
|
|
@ -114,7 +121,7 @@ MAOMOMO 暖橙金融教程风,画出一张手绘便签风仪表盘图。
|
|||
| `e-ink-editorial` | 深度解释、观点长文 | 纸感、黑白灰、少量强调色、元信息条 |
|
||||
| `scientific-defense` | 条款核对、规则证据链 | 严谨浅色版式、来源卡片、条件树 |
|
||||
| `mckinsey-brief` | 多方案对比、路径选择 | 结论先行、矩阵、取舍图、商业简报感 |
|
||||
| `xiaohongshu-vertical` | 小红书发布版、4 图看完 | 9:16 竖版、大字少字、强钩子、系列化版式 |
|
||||
| `xiaohongshu-vertical` | 小红书发布版、4 图看完、多图卡片 | 3:4 或 9:16 竖版、大字少字、强钩子、系列化版式 |
|
||||
|
||||
示例确认话术:
|
||||
|
||||
|
|
@ -143,7 +150,7 @@ C. handdrawn-note:便签和手绘箭头更明显,适合避坑经验和保姆
|
|||
|
||||
## 图片清单格式
|
||||
|
||||
生成图片前先规划清单,并同步写入 `prompts/{article_slug}_XX.json` 或图片 manifest。每个 prompt 文件至少包含:文件名、类型、放置位置、核心文案、可见文字白名单、alt text、风格、依赖素材、输出路径和完整 prompt。涉及信用卡、支付卡、支付网络或机构 Logo 时,还要包含参考素材、卡组织 / 支付网络、`allowed_brand_marks`、`brand_mark_sources` 和核对依据。
|
||||
生成图片前先规划清单,并同步写入 `prompts/{article_slug}_XX.json` 或图片 manifest。每个 prompt 文件至少包含:文件名、类型、放置位置、核心文案、可见文字白名单、alt text、风格、依赖素材、输出路径和完整 prompt。小红书卡片还必须包含 `aspect_ratio`、`visual_direction`、`portrait_composition_rules` 和分批交付批次。涉及信用卡、支付卡、支付网络或机构 Logo 时,还要包含参考素材、卡组织 / 支付网络、`allowed_brand_marks`、`brand_mark_sources` 和核对依据。
|
||||
|
||||
```markdown
|
||||
| 文件名 | 类型 | 放置位置 | 核心文案 | alt text | 风格 | 依赖素材 |
|
||||
|
|
@ -168,6 +175,10 @@ C. handdrawn-note:便签和手绘箭头更明显,适合避坑经验和保姆
|
|||
"visible_text_allowed": ["先报名,再看门槛和封顶", "MAOMOMO"],
|
||||
"alt_text": "MAOMOMO 汇丰 Mastercard 支付宝返现活动封面图",
|
||||
"style": "warm-fintech-guide",
|
||||
"aspect_ratio": "16:9",
|
||||
"visual_direction": "2D 扁平风",
|
||||
"delivery_batch": "batch-01-cover",
|
||||
"portrait_composition_rules": [],
|
||||
"required_assets": [],
|
||||
"reference_assets": [],
|
||||
"brand_mark_sources": [],
|
||||
|
|
@ -179,6 +190,17 @@ C. handdrawn-note:便签和手绘箭头更明显,适合避坑经验和保姆
|
|||
}
|
||||
```
|
||||
|
||||
小红书卡片 prompt JSON 中,`portrait_composition_rules` 必须包含:
|
||||
|
||||
```json
|
||||
[
|
||||
"native portrait composition",
|
||||
"no squeezed elements",
|
||||
"no stretched card / logo / text",
|
||||
"vertical layout redesigned for Xiaohongshu"
|
||||
]
|
||||
```
|
||||
|
||||
## 文件命名
|
||||
|
||||
图片文件名必须 SEO 友好,并包含主题前缀:
|
||||
|
|
@ -259,13 +281,17 @@ assets/
|
|||
|
||||
## 小红书图
|
||||
|
||||
用户说“小红书”“4 图看完”“发小红书”时:
|
||||
用户说“小红书”“卡片”“多图”“4 图看完”“发小红书”“3:4”“9:16”时:
|
||||
|
||||
- 生成 4 张 9:16 竖版 PNG,不复用文章横版图。
|
||||
- 进入小红书卡片模式,不默认生成完整文章、Markdown 或 ZIP。
|
||||
- 生成多张 3:4 或 9:16 竖版 PNG,默认 4 张;不复用文章横版图。
|
||||
- 出图前先确认 `2D 扁平风` / `3D 轻拟物风`;默认推荐 `2D 扁平风`。
|
||||
- 每张图有 MAOMOMO 标识或猫咪水印。
|
||||
- 手机端可读,大字少字。
|
||||
- 默认结构:封面、核心拆解、操作流程、避坑总结。
|
||||
- 风格固定为 `xiaohongshu-vertical`,不直接复用横版文章图。
|
||||
- 风格固定为 `xiaohongshu-vertical`,同组保持同一 `visual_direction`,不直接复用横版文章图。
|
||||
- prompt 必须包含 `native portrait composition`、`no squeezed elements`、`no stretched card / logo / text`、`vertical layout redesigned for Xiaohongshu`。
|
||||
- 通过 QA 后写入 `final_manifest.json`;最终交付只读取 final manifest 或状态文件中的 final assets。
|
||||
|
||||
## 图片 QA
|
||||
|
||||
|
|
@ -273,6 +299,8 @@ assets/
|
|||
|
||||
- 样张已被用户确认,后续图片没有切换生图后端或视觉风格。
|
||||
- 文件真实存在,格式为 PNG。
|
||||
- 小红书卡片比例为已确认的 `3:4` 或 `9:16`,不是横版图压缩或拉伸后的结果。
|
||||
- 小红书卡片是原生竖版重构,元素没有压扁,卡片、Logo 和文字没有拉伸。
|
||||
- `origin_image/` 原始最终图和 `assets/` 发布图对应。
|
||||
- Markdown 路径能打开对应文件。
|
||||
- 图片文字清楚,无乱码、错字、截断和多余文案。
|
||||
|
|
@ -287,6 +315,8 @@ assets/
|
|||
- 没有把示意图伪装成真实截图、账单、订单、App 页面或官方页面。
|
||||
- 每张图独立主题明确,不是同一画面的机械变体。
|
||||
- 单张 QA 通过后,才用 `scripts/maomomo_job_state.py result` 记录结果并同步到 `assets/`;不得只生成到 `origin_image/` 后声称完成。
|
||||
- 单张 QA 通过后,状态文件必须显示 `qa_status=passed`、`entered_assets=true`;GitHub 推送后必须记录 `github_pushed=true` 或对应 batch 记录。
|
||||
- 最终交付前必须生成 `final_manifest.json`,且只包含通过 QA 并进入 `assets/` 的最终文件。
|
||||
- `article.md` 已插入对应章节,且用脚本检查 Markdown 中所有图片路径真实存在。
|
||||
- `slide_jobs.json` / `slide_run_state.json` 中没有未处理的 `pending`、`dispatched` 或 `blocked` job;如有,不能声称完整交付完成。
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ STYLE_PRESETS: Dict[str, str] = {
|
|||
"白底纸感、手绘箭头、便利贴、重点圈注和轻量猫咪贴纸,适合避坑经验和保姆式步骤。"
|
||||
),
|
||||
"xiaohongshu-vertical": (
|
||||
"9:16 手机端可读,大字少字,强标题钩子,4 图系列一致视觉,带 MAOMOMO 标识。"
|
||||
"3:4 或 9:16 原生竖版,手机端可读,大字少字,强标题钩子,多图系列一致视觉,"
|
||||
"默认 2D 扁平信息卡片,用户确认后可用 3D 轻拟物风,带 MAOMOMO 标识。"
|
||||
),
|
||||
"clean-professional": (
|
||||
"浅色背景、蓝绿或暖橙强调、结构化信息卡片和清晰层级,适合正式银行规则、开户教程和综合攻略。"
|
||||
|
|
@ -267,6 +268,8 @@ def build_prompt(
|
|||
core_text: str,
|
||||
style: str,
|
||||
aspect_ratio: str,
|
||||
visual_direction: str = "",
|
||||
portrait_rules: str = "",
|
||||
extra: str = "",
|
||||
) -> str:
|
||||
allowed_visible = [value for value in (title, core_text, "MAOMOMO") if value.strip()]
|
||||
|
|
@ -281,6 +284,15 @@ def build_prompt(
|
|||
f"可见文字限制:画面只允许出现这些指定业务文案:{allowed_visible_text};如补充要求明确列出已核对的品牌或支付标识,可作为小型辅助标识出现;不要添加副标题、风格标签、prompt 描述、说明文字、额外 slogan 或无关文字。",
|
||||
"硬性要求:包含清晰可见的 MAOMOMO 主标识;中文文字清楚可读;信息层级明确;港币金额统一使用 HKD 写法;不要伪造真实 App 截图;Mastercard、Visa、UnionPay、银行、支付宝等 Logo 或支付网络标识只有在官方材料、用户素材或补充要求明确核对正确时才可出现,并且只能作为辅助识别,不能抢占或替代 MAOMOMO 主标识位置;未确认时使用通用卡片或通用支付符号,不要凭空加入或替换卡组织;不要出现真实个人信息;猫咪不穿戴第三方 Logo。",
|
||||
]
|
||||
if visual_direction.strip():
|
||||
parts.append(f"确认视觉方向:{visual_direction.strip()}。整组图片必须保持同一视觉方向,不得混用 2D 和 3D。")
|
||||
if style == "xiaohongshu-vertical" or aspect_ratio in {"3:4", "9:16"}:
|
||||
rules = portrait_rules.strip() or (
|
||||
"native portrait composition;no squeezed elements;"
|
||||
"no stretched card / logo / text;vertical layout redesigned for Xiaohongshu;"
|
||||
"禁止把横版设计硬塞进竖版画幅。"
|
||||
)
|
||||
parts.append(f"小红书竖图要求:{rules}")
|
||||
if extra.strip():
|
||||
parts.append(f"补充要求:{extra.strip()}")
|
||||
return "\n".join(parts)
|
||||
|
|
@ -352,6 +364,8 @@ def generate_one(args: argparse.Namespace) -> Dict[str, str]:
|
|||
core_text=args.core_text,
|
||||
style=args.style,
|
||||
aspect_ratio=args.aspect_ratio,
|
||||
visual_direction=args.visual_direction,
|
||||
portrait_rules=args.portrait_rules,
|
||||
extra=args.extra,
|
||||
)
|
||||
|
||||
|
|
@ -393,6 +407,12 @@ def batch(args: argparse.Namespace) -> List[Dict[str, str]]:
|
|||
die(f"manifest 第 {index} 项缺少 file_name。")
|
||||
style = str(item.get("style") or args.style or DEFAULT_STYLE)
|
||||
aspect_ratio = str(item.get("aspect_ratio") or args.aspect_ratio)
|
||||
visual_direction = str(item.get("visual_direction") or args.visual_direction or "")
|
||||
raw_portrait_rules = item.get("portrait_composition_rules") or args.portrait_rules
|
||||
if isinstance(raw_portrait_rules, list):
|
||||
portrait_rules = ";".join(str(value) for value in raw_portrait_rules)
|
||||
else:
|
||||
portrait_rules = str(raw_portrait_rules or "")
|
||||
prompt = item.get("prompt")
|
||||
if not isinstance(prompt, str) or not prompt.strip():
|
||||
prompt = build_prompt(
|
||||
|
|
@ -401,6 +421,8 @@ def batch(args: argparse.Namespace) -> List[Dict[str, str]]:
|
|||
core_text=str(item.get("core_text") or item.get("caption") or item.get("alt_text") or ""),
|
||||
style=style,
|
||||
aspect_ratio=aspect_ratio,
|
||||
visual_direction=visual_direction,
|
||||
portrait_rules=portrait_rules,
|
||||
extra=str(item.get("extra") or item.get("requirements") or ""),
|
||||
)
|
||||
|
||||
|
|
@ -439,6 +461,8 @@ def build_parser() -> argparse.ArgumentParser:
|
|||
common.add_argument("--quality", default=DEFAULT_QUALITY)
|
||||
common.add_argument("--output-format", default="png")
|
||||
common.add_argument("--aspect-ratio", default="16:9")
|
||||
common.add_argument("--visual-direction", default="")
|
||||
common.add_argument("--portrait-rules", default="")
|
||||
common.add_argument("--dry-run", action="store_true", help="Only write prompt files; do not call the image API.")
|
||||
|
||||
generate = subparsers.add_parser("generate", parents=[common], help="Generate one image.")
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ from typing import Any, Dict, Iterable, List, Optional, Tuple
|
|||
|
||||
JOBS_FILE = "slide_jobs.json"
|
||||
STATE_FILE = "slide_run_state.json"
|
||||
FINAL_MANIFEST_FILE = "final_manifest.json"
|
||||
GITHUB_BATCHES_FILE = "github_batches.json"
|
||||
|
||||
|
||||
def now_iso() -> str:
|
||||
|
|
@ -64,6 +66,13 @@ def resolve_in_project(project: Path, value: str) -> Path:
|
|||
return path.resolve()
|
||||
|
||||
|
||||
def relative_path_string(project: Path, path: Path) -> str:
|
||||
try:
|
||||
return str(path.resolve().relative_to(project))
|
||||
except ValueError:
|
||||
return str(path.resolve())
|
||||
|
||||
|
||||
def load_job_doc(project: Path) -> Dict[str, Any]:
|
||||
raw = read_json(project / JOBS_FILE)
|
||||
if isinstance(raw, list):
|
||||
|
|
@ -88,6 +97,18 @@ def load_state_doc(project: Path) -> Dict[str, Any]:
|
|||
return raw
|
||||
|
||||
|
||||
def load_batches_doc(project: Path) -> Dict[str, Any]:
|
||||
path = project / GITHUB_BATCHES_FILE
|
||||
if not path.exists():
|
||||
return {"version": 1, "batches": []}
|
||||
raw = read_json(path)
|
||||
if not isinstance(raw, dict):
|
||||
die(f"{GITHUB_BATCHES_FILE} 必须是对象。")
|
||||
if not isinstance(raw.get("batches"), list):
|
||||
raw["batches"] = []
|
||||
return raw
|
||||
|
||||
|
||||
def save_docs(project: Path, job_doc: Dict[str, Any], state_doc: Dict[str, Any]) -> None:
|
||||
write_json(project / JOBS_FILE, job_doc)
|
||||
write_json(project / STATE_FILE, state_doc)
|
||||
|
|
@ -159,6 +180,14 @@ def cmd_init(args: argparse.Namespace) -> int:
|
|||
"asset_out": infer_asset_out(data, origin_out),
|
||||
"status": "pending",
|
||||
"selected_backend": args.selected_backend,
|
||||
"aspect_ratio": data.get("aspect_ratio", ""),
|
||||
"visual_direction": data.get("visual_direction", ""),
|
||||
"delivery_batch": data.get("delivery_batch", ""),
|
||||
"qa_status": "pending",
|
||||
"entered_assets": False,
|
||||
"final": False,
|
||||
"github_pushed": False,
|
||||
"github_batch": "",
|
||||
"created_at": now_iso(),
|
||||
}
|
||||
)
|
||||
|
|
@ -186,7 +215,9 @@ def cmd_status(args: argparse.Namespace) -> int:
|
|||
print(json.dumps({"project": str(project), "counts": counts}, ensure_ascii=False, indent=2))
|
||||
for job in job_doc["jobs"]:
|
||||
if isinstance(job, dict):
|
||||
print(f"{job_key(job) or '<unknown>'}\t{job.get('status', 'unknown')}\t{job.get('origin_out', '')}")
|
||||
github = "github" if job.get("github_pushed") else "local"
|
||||
qa = job.get("qa_status", "")
|
||||
print(f"{job_key(job) or '<unknown>'}\t{job.get('status', 'unknown')}\t{qa}\t{github}\t{job.get('origin_out', '')}")
|
||||
return 0
|
||||
|
||||
|
||||
|
|
@ -238,19 +269,25 @@ def cmd_result(args: argparse.Namespace) -> int:
|
|||
copy_if_needed(source, origin_out)
|
||||
|
||||
asset_value = args.asset_out or job.get("asset_out")
|
||||
entered_assets = False
|
||||
if isinstance(asset_value, str) and asset_value:
|
||||
copy_if_needed(origin_out, resolve_in_project(project, asset_value))
|
||||
entered_assets = True
|
||||
|
||||
result = {
|
||||
"agent_id": args.agent_id,
|
||||
"backend_used": args.backend_used,
|
||||
"selected_source": str(source),
|
||||
"origin_out": str(origin_out.relative_to(project) if origin_out.is_relative_to(project) else origin_out),
|
||||
"origin_out": relative_path_string(project, origin_out),
|
||||
"asset_out": asset_value,
|
||||
"qa_status": "passed",
|
||||
"entered_assets": entered_assets,
|
||||
"qa_note": args.qa_note,
|
||||
"time": now_iso(),
|
||||
}
|
||||
job["status"] = "recorded"
|
||||
job["qa_status"] = "passed"
|
||||
job["entered_assets"] = entered_assets
|
||||
job["result"] = result
|
||||
event(state_doc, "result", args.job, result)
|
||||
save_docs(project, job_doc, state_doc)
|
||||
|
|
@ -277,6 +314,177 @@ def cmd_blocker(args: argparse.Namespace) -> int:
|
|||
return 0
|
||||
|
||||
|
||||
def cmd_final_manifest(args: argparse.Namespace) -> int:
|
||||
project = project_path(args.project)
|
||||
job_doc = load_job_doc(project)
|
||||
state_doc = load_state_doc(project)
|
||||
assets: List[Dict[str, Any]] = []
|
||||
incomplete: List[str] = []
|
||||
|
||||
for job in job_doc["jobs"]:
|
||||
if not isinstance(job, dict):
|
||||
continue
|
||||
key = job_key(job) or "<unknown>"
|
||||
if job.get("status") != "recorded":
|
||||
incomplete.append(f"{key}: status={job.get('status', 'unknown')}")
|
||||
continue
|
||||
if job.get("qa_status") != "passed":
|
||||
incomplete.append(f"{key}: qa_status={job.get('qa_status', 'unknown')}")
|
||||
continue
|
||||
if job.get("entered_assets") is not True:
|
||||
incomplete.append(f"{key}: entered_assets=false")
|
||||
continue
|
||||
|
||||
result = job.get("result") if isinstance(job.get("result"), dict) else {}
|
||||
asset_value = result.get("asset_out") or job.get("asset_out")
|
||||
if not isinstance(asset_value, str) or not asset_value:
|
||||
incomplete.append(f"{key}: 缺少 asset_out")
|
||||
continue
|
||||
|
||||
asset_path = resolve_in_project(project, asset_value)
|
||||
if not asset_path.exists():
|
||||
incomplete.append(f"{key}: assets 文件不存在:{asset_value}")
|
||||
continue
|
||||
|
||||
job["final"] = True
|
||||
assets.append(
|
||||
{
|
||||
"id": key,
|
||||
"prompt_file": job.get("prompt_file", ""),
|
||||
"origin_out": result.get("origin_out") or job.get("origin_out", ""),
|
||||
"asset_out": relative_path_string(project, asset_path),
|
||||
"qa_status": job.get("qa_status", ""),
|
||||
"qa_note": result.get("qa_note", ""),
|
||||
"aspect_ratio": job.get("aspect_ratio", ""),
|
||||
"visual_direction": job.get("visual_direction", ""),
|
||||
"delivery_batch": job.get("delivery_batch", ""),
|
||||
"github_pushed": bool(job.get("github_pushed")),
|
||||
"github_batch": job.get("github_batch", ""),
|
||||
}
|
||||
)
|
||||
|
||||
if incomplete and not args.allow_incomplete:
|
||||
die("仍有未进入最终 manifest 的图片 job:\n" + "\n".join(incomplete))
|
||||
if not assets:
|
||||
die("没有可写入 final_manifest.json 的最终图片。")
|
||||
|
||||
manifest_path = resolve_in_project(project, args.out)
|
||||
manifest = {
|
||||
"version": 1,
|
||||
"generated_at": now_iso(),
|
||||
"project": project.name,
|
||||
"asset_count": len(assets),
|
||||
"assets": assets,
|
||||
}
|
||||
write_json(manifest_path, manifest)
|
||||
event(
|
||||
state_doc,
|
||||
"final_manifest",
|
||||
"*",
|
||||
{
|
||||
"path": relative_path_string(project, manifest_path),
|
||||
"asset_count": len(assets),
|
||||
"allow_incomplete": args.allow_incomplete,
|
||||
},
|
||||
)
|
||||
save_docs(project, job_doc, state_doc)
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
"status": "final_manifest_written",
|
||||
"path": relative_path_string(project, manifest_path),
|
||||
"assets": len(assets),
|
||||
},
|
||||
ensure_ascii=False,
|
||||
indent=2,
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_github_batch(args: argparse.Namespace) -> int:
|
||||
project = project_path(args.project)
|
||||
job_doc = load_job_doc(project)
|
||||
state_doc = load_state_doc(project)
|
||||
batches_doc = load_batches_doc(project)
|
||||
|
||||
rel_paths: List[str] = []
|
||||
for value in args.paths:
|
||||
path = resolve_in_project(project, value)
|
||||
if not path.exists():
|
||||
die(f"批次文件不存在:{value}")
|
||||
rel_paths.append(relative_path_string(project, path))
|
||||
|
||||
path_set = set(rel_paths)
|
||||
pushed_jobs: List[str] = []
|
||||
for job in job_doc["jobs"]:
|
||||
if not isinstance(job, dict):
|
||||
continue
|
||||
result = job.get("result") if isinstance(job.get("result"), dict) else {}
|
||||
candidate_values = [job.get("asset_out"), result.get("asset_out")]
|
||||
normalized = {
|
||||
relative_path_string(project, resolve_in_project(project, value))
|
||||
for value in candidate_values
|
||||
if isinstance(value, str) and value
|
||||
}
|
||||
if normalized.intersection(path_set):
|
||||
job["github_pushed"] = True
|
||||
job["github_batch"] = args.batch
|
||||
if isinstance(job.get("result"), dict):
|
||||
job["result"]["github_pushed"] = True
|
||||
job["result"]["github_batch"] = args.batch
|
||||
pushed_jobs.append(job_key(job) or "<unknown>")
|
||||
|
||||
batch_record = {
|
||||
"batch": args.batch,
|
||||
"commit": args.commit,
|
||||
"url": args.url,
|
||||
"release": args.release,
|
||||
"paths": rel_paths,
|
||||
"pushed_jobs": pushed_jobs,
|
||||
"note": args.note,
|
||||
"time": now_iso(),
|
||||
}
|
||||
batches = [item for item in batches_doc["batches"] if not (isinstance(item, dict) and item.get("batch") == args.batch)]
|
||||
batches.append(batch_record)
|
||||
batches_doc["batches"] = batches
|
||||
|
||||
manifest_path = project / FINAL_MANIFEST_FILE
|
||||
if manifest_path.exists():
|
||||
manifest = read_json(manifest_path)
|
||||
if isinstance(manifest, dict) and isinstance(manifest.get("assets"), list):
|
||||
for item in manifest["assets"]:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
asset_value = item.get("asset_out")
|
||||
if not isinstance(asset_value, str) or not asset_value:
|
||||
continue
|
||||
normalized = relative_path_string(project, resolve_in_project(project, asset_value))
|
||||
if normalized in path_set:
|
||||
item["github_pushed"] = True
|
||||
item["github_batch"] = args.batch
|
||||
item["github_commit"] = args.commit
|
||||
item["github_url"] = args.url
|
||||
write_json(manifest_path, manifest)
|
||||
|
||||
write_json(project / GITHUB_BATCHES_FILE, batches_doc)
|
||||
event(state_doc, "github_batch", "*", batch_record)
|
||||
save_docs(project, job_doc, state_doc)
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
"status": "github_batch_recorded",
|
||||
"batch": args.batch,
|
||||
"paths": len(rel_paths),
|
||||
"pushed_jobs": pushed_jobs,
|
||||
},
|
||||
ensure_ascii=False,
|
||||
indent=2,
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
def build_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(description="Record MAOMOMO article image job state.")
|
||||
subparsers = parser.add_subparsers(dest="command", required=True)
|
||||
|
|
@ -317,6 +525,22 @@ def build_parser() -> argparse.ArgumentParser:
|
|||
blocker.add_argument("--reason", required=True)
|
||||
blocker.add_argument("--evidence", default="")
|
||||
blocker.set_defaults(func=cmd_blocker)
|
||||
|
||||
final_manifest = subparsers.add_parser("final-manifest", help="Write final_manifest.json from recorded assets.")
|
||||
final_manifest.add_argument("project")
|
||||
final_manifest.add_argument("--out", default=FINAL_MANIFEST_FILE)
|
||||
final_manifest.add_argument("--allow-incomplete", action="store_true")
|
||||
final_manifest.set_defaults(func=cmd_final_manifest)
|
||||
|
||||
github_batch = subparsers.add_parser("github-batch", help="Record a GitHub delivery batch.")
|
||||
github_batch.add_argument("project")
|
||||
github_batch.add_argument("--batch", required=True)
|
||||
github_batch.add_argument("--commit", required=True)
|
||||
github_batch.add_argument("--url", required=True)
|
||||
github_batch.add_argument("--release", default="")
|
||||
github_batch.add_argument("--paths", nargs="+", required=True)
|
||||
github_batch.add_argument("--note", default="")
|
||||
github_batch.set_defaults(func=cmd_github_batch)
|
||||
return parser
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue