Agent Skills › imcuttle/flipbook-app

imcuttle/flipbook-app

GitHub

将画册导出为图文素材包并发布至抖音。分两阶段:先通过脚本按序导出图片与文案,再经浏览器自动化填充创作者中心内容。严格限制不自动点击发布,确保用户最终确认,避免操作风险。

4 skills 340

Install All Skills

npx skills add imcuttle/flipbook-app --all -g -y
More Options

List skills in collection

npx skills add imcuttle/flipbook-app --list

Skills in Collection (4)

将画册导出为图文素材包并发布至抖音。分两阶段:先通过脚本按序导出图片与文案,再经浏览器自动化填充创作者中心内容。严格限制不自动点击发布,确保用户最终确认,避免操作风险。
画册发抖音 export canvas to social 发布到抖音 canvas 转图文
.codebuddy/skills/canvas-to-social/SKILL.md
npx skills add imcuttle/flipbook-app --skill canvas-to-social -g -y
SKILL.md
Frontmatter
{
    "name": "canvas-to-social",
    "description": "当需要把 flipbook-skill 画册(按 canvasId)转成社交平台图文时使用 —— 包括把节点图片+文案导出为素材包,以及把内容发布到抖音(creator.douyin.com)。触发词:画册发抖音、export canvas to social、发布到抖音、canvas 转图文。"
}

画册转社交图文 (canvas-to-social)

概述

有意拆成两个独立阶段:

  1. 导出(确定性、可脚本化、平台无关):从 flipbook-skill 数据存储读取一个画册,生成 social-export/<主题>/ 包——图片按阅读顺序重命名,外加 文案.md(主帖正文+逐图说明) 和 manifest.json。这份导出包与具体平台无关,可复用于任意目标平台。
  2. 发布(浏览器自动化、需人工判断、按平台不同):操作已登录的创作者中心网页,上传图片、 填标题/正文、选音乐/话题、可选地选合集——然后停下来,让用户自己点「发布」

支持的发布平台(细节见各自的 reference):

  • 抖音references/publishing-douyin.md(creator.douyin.com,图片 ≤ 35 张,可选 BGM/合集)。

目前仅抖音发布流程已实测可用。未来要新增平台(如小红书)时,按本目录的 publishing-douyin.md 结构新增一份 publishing-<平台>.md,并在上表登记即可—— 导出阶段无需改动。

何时使用

  • "把某画册/canvas 发成抖音图文" / "export canvas to social" / "发布到抖音"。
  • 你拿到了一个 canvasId(位于 server/data/canvases/ 下的文件夹)。
  • 只要图片+文案时,单独用阶段一;要自动填充帖子时,再加上阶段二(按目标平台选对应 reference)。

阶段一 —— 导出(平台无关)

运行脚本(仅用标准库,无第三方依赖)。--data-root 默认是 server/data;如果当前 工作目录不是 app 根目录则需覆盖。

python3 scripts/export_canvas.py <canvasId> \
  --data-root /path/to/app/server/data \
  --limit 35 \
  --hashtags "#话题1 #话题2"
  • BFS(根节点优先)排序 → 图片命名为 01-标题.pngNN-标题.png
  • --limit 35 强制套用抖音图文上限;超过 35 会打印警告。
  • 输出目录默认 social-export/<主题>;脚本最后会打印 OUT_DIR=...

随后和用户一起打磨文案:原始图说偏百科书面语。主动提议:(a) 挑出最佳 N 张图, (b) 改写成口语化、有钩子的短文案 + 吸睛标题。务必遵守目标平台的字数/图片上限 (抖音:标题 ≤ 20 字、正文 ≤ 1000 字、图片 ≤ 35 张,详见 references/publishing-douyin.md)。

阶段二 —— 发布(可选,按平台分流)

必须:用 browser SKILL(CDP)驱动用户已登录的 Chrome。 browser-harness 命令需已在 $PATH 上(单独安装)。

按目标平台打开对应 reference 逐步执行:

目标平台 reference 图片上限 关键差异
抖音 references/publishing-douyin.md 35 有 BGM、有「图解世界」合集

抖音发布骨架(细节严格按 references/publishing-douyin.md 第 1-7 步):

步骤 操作 关键坑
1 打开 creator.douyin.com → 发布图文 按文字定位入口,别用固定坐标
2 上传图片 用 harness 的 upload_file(选择器, 排序列表),别手写 raw cdp
3 标题(≤20字) 用 prototype value setter + 派发 input/change 事件
4 正文(≤1000字) contenteditable 用 execCommand('insertText');话题写成纯文本 #词
5 音乐 「使用」按钮只在悬停某行时出现;派发 hover 事件后再 .click()
6 合集(可选) 存在「图解世界」就选,否则跳过;绝不自动新建
7 校验 + 停手 报告状态;定位「发布」按钮但绝不点击

唯一铁律

永远不点最终的「发布」按钮。 它不可逆且对外公开。填好所有内容、校验,然后把 最后一步交给用户。「存草稿」仅在用户明确要求时才点。

不要读图

不要用 Read 工具去查看/识别导出的图片本身。 文案一律基于 文案.md 的文字图说改写, 图片只按 manifest.json 的阅读顺序原样上传。无需打开、预览或多模态识别任何 .png。 (核对上传结果时也用 js() 读取页面 DOM/计数,而非看图。)

常见错误

  • 跨步骤复用坐标。 页面会滚动和重渲染;每次点击前都按文字/placeholder 重新查询 元素位置。
  • 往标题/正文里用 type_text React/Semi 输入框会丢键或截断。改用对应 reference 里的 value-setter / execCommand 写法。
  • 手写 cdp("DOM.setFileInputFiles", …) 加手动遍历节点树。 很脆弱,且 cdp() helper 会拒绝带 sessionId 的键。用 upload_file
  • 未经确认就发布。 不要。停在发布前那一步。
  • 导出超过平台上限还全部上传。 抖音上限 35;超出会被拒收/截断。
批量将网络热点转化为竖版画册。先联网筛选安全热点并生成包含根图及10+下钻图的配置,再自动启动服务利用CodeBuddy生成图片,全程去重且服务自启自关,避免重复劳动。
热点画册 批量生成画册 网络热点做画册 build hot canvases canvas 批量下钻 热搜做成画册
.codebuddy/skills/hot-canvas-batch/SKILL.md
npx skills add imcuttle/flipbook-app --skill hot-canvas-batch -g -y
SKILL.md
Frontmatter
{
    "name": "hot-canvas-batch",
    "description": "当需要把网络热点\/流量高的内容批量做成 flipbook-skill 画册(canvas)时使用——联网搜当日热点、为每个选题生成根图+10+张下钻图的竖版画册,服务自启自关、近3个月同主题自动去重。触发词:热点画册、批量生成画册、网络热点做画册、build hot canvases、canvas 批量下钻、热搜做成画册。"
}

热点画册批量生成 (hot-canvas-batch)

概述

两阶段,职责分明:

  1. 选题(你来做,需联网+人工判断):联网搜当日热点,挑 1-3 个流量高的选题, 为每个选题写一份 themes.json——含根图主题 + ≥10 个下钻 label。
  2. 建册(脚本全自动)build_canvases.mjs 自己挑空闲端口启动 flipbook server (强制 ENABLE_CODEBUDDY=1,用 codebuddy 出图,不依赖 OpenAI)→ 逐个建竖版 画册 → 每册根图 + 10 个 label 下钻 → 写带日期的历史记录 → 无论成功/报错/Ctrl-C 都 kill 掉 server。(脚本耗时较长,30min~1h)

何时使用

  • "收集网络热点做成画册" / "批量生成画册" / "热搜做成 canvas"。
  • 用户要一次产出多个画册、每册要够多图(≥10 张下钻)。

唯一铁律

选题阶段必须过滤政治敏感话题——不碰政治人物、政治制度、政府机构、选举、 地缘冲突等。只选娱乐、科技、体育、游戏、生活、文化等安全热点。这条优先级最高。

阶段一 —— 选题,写 themes.json

  1. 先看已发布的主题(去重前置):选题前先列出近 N 天已经做过的画册主题, 避免重复选题、白费搜索功夫。运行:

    node ./scripts/list_recent_topics.mjs           # 人读列表,近 90 天,最新在前
    # node ./scripts/list_recent_topics.mjs --json  # 机读 JSON
    # RECENT_DAYS=30 node ./scripts/list_recent_topics.mjs  # 收窄时间窗
    

    这个脚本直接读 topics-history/*/run.json、不起服务、不联网。把输出里的 topic + aliases 当作"黑名单":搜热点 / 挑选题时就主动避开这些已发布主题 (含近义说法)。这样在选题阶段就完成去重,而不是等到阶段二建册时才被 SKIP。

  2. 用 WebSearch 搜当日热点(如票房榜、电竞赛事、AI 动态、热门影视/综艺等), 抓取具体事实(数字、事件、名称),这些会成为下钻 label。挑选题时对照第 1 步 的已发布列表,命中(或近义)的直接换别的热点。

  3. scripts/themes.example.json 的结构写一份 themes 文件。字段:

[
  {
    "topic": "根图主题(一句话,作画册根图标题)",
    "aliases": ["去重关键词1", "去重关键词2"],
    "style": "按主题挑的风格(见下方风格列表,如 popart/goldluxe/kawaii…)",
    "branches": 5,
    "drills": ["下钻子图1", "下钻子图2", "...", "下钻子图10"]
  }
]
  • topic:根节点主题,会触发一张全景信息图。
  • aliases:去重用的近义关键词(脚本归一化后做包含匹配)。写全一点,避免下次 换个说法又重复生成。
  • style为每个 theme 挑一个最契合的视觉风格(从下方「风格列表(12 种)」 里按"适用主题"列匹配)。这是避免产出趋同的关键——不要清一色 cinematic。同一批 多个 theme 尽量挑不同风格,特色越鲜明越好。themes.json 里的 style 字段 优先级高于命令行 STYLE=(见下方优先级)。
  • drills:每条是一个下钻子图的主题 label。脚本走 /api/canvas/:id/click/uploadlabel 覆盖路径——子图内容由 label 决定,不靠点击坐标语义(坐标只用来在 画面上铺开热点锚点,避免引导线重叠)。所以 label 要写成具体、自洽的主题句。
  • 至少写 10 条 drills(DRILL_PER 默认取前 10 条)。

阶段二 —— 跑脚本(单条命令,服务自启自关)

node ./scripts/build_canvases.mjs --themes /path/to/themes.json

脚本会:挑空闲端口 → spawn server → 等就绪 → 去重 → 建册 → 写历史 → kill server。 不需要你手动起服务,也不需要你记得关。

flag / env

名称 默认 说明
--themes <path> 必填 themes JSON 文件路径
--app-dir <path> 自动推断 flipbook app 根目录;脚本不在 app 内时需指定
--keep-server 调试用,结束后保留 server 不 kill
PORT 自动挑空闲端口 指定则用固定端口
ORIENTATION portrait 画册方向,竖版/横版
STYLE 全局/轮询风格(如 popartpopart,kawaii,pixel)。推荐改用 themes.json 里每个 theme 的 style 字段按主题挑,优先级高于 STYLE;显式 PROMPTS_DIR 又高于二者
PROMPTS_DIR 直接指定 prompt 模板目录,覆盖 STYLE 的默认选择
RECENT_DAYS 90 去重时间窗(近 N 天同主题跳过)
DRILL_PER 10 每册下钻子节点数
ENABLE_OCR 0(关) 建册默认关掉 Apple Vision OCR 文字层;设 1 重新开启
ENABLE_AUDIO 0(关) 建册默认关掉 macOS say 旁白音频;设 1 重新开启
DRY_RUN=1 起服务→打印去重计划→关服务,不建册(用于验证 themes/去重)

注:批量建册默认关闭 OCR 与音频——下游 canvas-to-social 导出不消费文字层/旁白, 且二者各自给每张图增加一次额外处理开销。需要时用 ENABLE_OCR=1 / ENABLE_AUDIO=1 开回。

建议先 DRY_RUN=1 跑一遍确认选题不会被去重命中,再正式建。

视觉风格(STYLE 开关)

默认用项目原始风格(米色 isometric 信息图,即"百科知识"风)——当既没指定 themes.jsonstyle、也没传 STYLE= / PROMPTS_DIR= 时生效,对应 app/prompts/ 目录。通过 STYLE= 切换风格包,支持按主题指定全局轮询

风格列表(12 种 + 默认)

默认风格(不传任何 STYLE/style/PROMPTS_DIR):米色 isometric 信息图, 偏中性百科知识感,适合工具/教程/通用科普。下面 12 种是可显式切换的风格包。

重要:模型必须按主题为每个 theme 自动挑选最契合的风格(见阶段一第 4 步), 不要清一色用 cinematic。同一批多个 theme 尽量挑不同风格,让产出有辨识度、不趋同。

STYLE 值 风格名 视觉特征 适用主题
cinematic 深海电影感 深蓝渐变、生物发光、体积光、暗色电影感 科技/揭秘/深度/悬疑
vaporwave 蒸汽波 紫粉青渐变、霓虹网格地平线、罗马石膏像、80s 故障感 潮流/音乐/复古未来/二次元
claymorphism 黏土3D 软萌 3D 黏土质感、圆润体块、柔和投影、马卡龙撞色 生活/教程/产品/萌系
risograph 套印孔版 2-3 色叠印错位、颗粒噪点、荧光粉蓝、复古印刷 文艺/活动/海报/手作
holographic 全息镭射 镭射彩虹渐变、液态金属反光、Y2K、未来高级感 美妆/数码/潮品/科技
papercut 剪纸分层 多层纸艺立体景深、清晰阴影、鲜明撞色 故事/节日/文化/传统
popart 波普漫画 漫画网点、粗黑描边、爆炸框 BAM/WOW、原色高饱和 娱乐/八卦/趣味/猎奇
kawaii 治愈卡通 圆润扁平卡通、糖果色、大眼贴纸、可爱吉祥物 育儿/萌宠/情感/轻科普
goldluxe 鎏金奢华 黑金配色、烫金质感、大理石纹、聚光灯、高级杂志感 财经/奢侈品/高端/汽车
airbrush70s 复古喷绘 70s 喷枪渐变、暖色日落条纹、颗粒、复古海报 旅行/音乐/怀旧/慢生活
glassmorphism 毛玻璃 半透磨砂玻璃卡片、彩色光晕背景、模糊层叠、现代 UI 感 科技/金融/数据/产品
pixel 复古像素 8-bit 像素网格、限色板、扫描线、街机游戏感 游戏/怀旧/80-90s/电竞

使用方式

方式一(推荐):按主题指定风格——themes.json 中每个 theme 带一个 style 字段, 模型选题时就按"适用主题"挑好,这是避免趋同的关键

[
  {
    "topic": "顶流明星塌房始末",
    "style": "popart",
    "aliases": ["塌房", "明星八卦"],
    "drills": ["事件时间线", "粉丝反应", "..."]
  },
  {
    "topic": "新能源汽车销量榜",
    "style": "goldluxe",
    "aliases": ["新能源", "销量榜"],
    "drills": ["销量第一", "续航对比", "..."]
  }
]

不带 style 字段时,回退到命令行 STYLE= 或项目默认。

方式二:全局统一风格(整批用同一种)

STYLE=glassmorphism node ./scripts/build_canvases.mjs --themes /path/to/themes.json

方式三:多风格轮询(逗号分隔,多个 canvas 时依次轮用)

STYLE=popart,kawaii,pixel node ./scripts/build_canvases.mjs --themes /path/to/themes.json

方式四:完全自定义——复制任意 prompts-<style>/ 目录,改写后直接用 PROMPTS_DIR 指向:

PROMPTS_DIR=/path/to/my-custom-prompts node ./scripts/build_canvases.mjs --themes ...

风格包结构

每个风格对应 prompts-<style>/ 目录(位于 skills/hot-canvas-batch/ 下),包含:

  • system.md — 全局视觉约束
  • image-prompt.md — 风格后缀(引擎用 > 引用 + 反引号格式提取)
  • planner.md — 文案风格(标题字数/正文语气)
  • click-label.mddecide-search.md — 通常复用,无需修改

优先级

显式 PROMPTS_DIR=xxx > themes.jsonstyle 字段 > STYLE= 环境变量 > 项目默认(米色 isometric)

去重机制(两道防线)

两个阶段都基于同一份历史数据 <app>/topics-history/*/run.json,归一化口径一致 (topic+aliases 去空格/标点/大小写后做包含匹配):

  1. 选题阶段(前置,推荐):跑 list_recent_topics.mjs 列出近 RECENT_DAYS 天 已发布主题,搜热点时就主动避开——从源头省掉重复选题与无谓搜索。
  2. 建册阶段(兜底)build_canvases.mjs 起服务后会再扫一遍历史,对本次 themes 逐条做包含匹配,命中则 SKIP(控制台打印 SKIP "..." (recent duplicate of "..."))。

两层用同一逻辑,前置那层让你尽早换题,兜底那层保证万一漏了也不会重复生成。 所以每次换新热点即可,老主题不会被重复生成。

产物

  • 画册数据:<app>/server/data/canvases/<canvasId>/(manifest / tree.json / nodes / images)。
  • 历史记录:<app>/topics-history/<YYYY-MM-DD_HHMMSS>/run.json,含 {canvasId, topic, aliases, orientation, nodeCount}不存 url——端口是临时的、 服务会被关掉,url 没有意义;要看画册时另起服务再访问 /?c=<canvasId>

每册图片数与结构

  • 根图 1 张(全景信息长卷)+ 10 个一级下钻 = 11 张,每册稳定 ≥10 张。
  • 想要更多层级/更多图:建完后对某些一级子节点再 click 下钻一层(depth 2), 或调大 DRILL_PER

常见坑

  • codebuddy planner 偶发 JSON 解析失败 → 个别下钻节点缺图(tree 有节点但 images/ 下无对应 .png)。补救:POST /api/canvas/:id/nodes/:hash/regenerate,或对根图再补 一个 label 下钻。脚本的 settle 阶段会等重试落盘。
  • 每个父节点并发上限 4(server 端 MAX_PARALLEL_CLICKS_PER_NODE)。脚本按 ~800ms 间隔投递、整体串行等待,不会触顶;手动批量 click 时注意别一次性超过 4 个。
  • 根图较慢:planner(联网搜索+规划,≤90s)+ 图片生成(≤180s),根图就绪通常 1-4 分钟,属正常,不要误判卡死。
  • --app-dir:脚本默认从自身路径上溯 4 级定位 app 根。若把脚本拷到别处运行, 必须用 --app-dir 指向 flipbook app 根目录(含 server/src/index.js 的那层)。
端到端编排Skill,串联热点搜索、画册生成与抖音发布。自动过滤敏感话题,并行导出润色文案,最后填充多Tab待发布状态,严守不自动发布铁律。
热点做成抖音 批量发抖音图文 热点画册发抖音 canvas 转抖音批量 热搜一键图文 end-to-end social
.codebuddy/skills/hot-canvas-to-social/SKILL.md
npx skills add imcuttle/flipbook-app --skill hot-canvas-to-social -g -y
SKILL.md
Frontmatter
{
    "name": "hot-canvas-to-social",
    "description": "端到端把网络热点做成画册并发布成社交图文。先调用 hot-canvas-batch 产出 N 个热点画册(canvas),再基于产出的画册进入 canvas-to-social 完成导出+文案润色+多 tab 填充,最后停在「发布」交给用户。触发词:热点做成抖音、批量发抖音图文、热点画册发抖音、canvas 转抖音批量、热搜一键图文、end-to-end social。"
}

热点画册 → 社交图文 端到端编排 (hot-canvas-to-social)

这是什么

一个编排 skill,把两个已有 skill 串起来跑完整链路:

WebSearch 热点 → [hot-canvas-batch] 产出 N 个画册 → [canvas-to-social] 导出+润色+多tab填充 → 停在发布

它自己不重复实现建册或发布逻辑——而是按顺序调用

  1. hot-canvas-batch(建册,服务自启自关)。
  2. canvas-to-social(导出 + 浏览器自动化填充)。

目前发布目标仅支持抖音canvas-to-social/references/publishing-douyin.md)。 未来新增平台时,导出阶段不变,只需在阶段 3 增加对应平台的填充流程。

何时使用

  • "收集热点做成画册并发到抖音" / "批量把热搜做成抖音图文" / "一键热点图文"。
  • 用户想要从「找选题」到「待发布的抖音草稿」全程自动化,最后人工点发布。

唯一铁律(三条,最高优先级)

  1. 选题阶段必须过滤政治敏感话题——只选娱乐/科技/体育/游戏/生活/文化等安全热点。
  2. 永远不点最终「发布」按钮——发布不可逆、对外公开。所有 tab 填好内容、校验、 停在发布按钮前,把最后一步交给用户。仅当用户明确要求才点「存草稿」。
  3. 不要读图——不用 Read 工具去查看/识别导出的 .png。文案一律基于 文案.md 的文字 图说改写,图片只按阅读顺序原样上传;核对上传结果用 js() 读 DOM/计数,而非看图。

页面易变,每次自更新

抖音创作者中心 DOM/class/文案变化快。阶段 3 的所有浏览器选择器都是实测快照、可能失效。 执行时遵循「先探测 → 失效就按可见文字兜底 → 把新规则用 Edit 回写 canvas-to-social/references/publishing-douyin.md(及本文件摘要)」的闭环,保证下次拿到最新规则。 详见 publishing-douyin.md 顶部「自更新约定」。

参数

开工前先和用户确认(用 AskUserQuestion):

  • N:做几个画册 / 发几条图文(默认 3,每画册 ≈10-15 张图)。
  • 方向:竖版 portrait(抖音图文推荐)/ 横版。
  • 合集:默认全部归入抖音「图解世界」合集(存在就选,不存在则跳过、不新建)。

阶段 0 —— 选题(你来做,需联网)

用 WebSearch 搜当日热点,挑 N 个流量高且非政治敏感的选题。为每个选题抓具体事实 (数字、事件、名称)作为下钻 label。把选题写成 <root>/themes.json(结构见 ../hot-canvas-batch/SKILL.md 中的 themes.example.json)。

阶段 1 —— 建册(调用 hot-canvas-batch)

跑一条命令,脚本自启服务、建册、自关服务、写历史:

node ../hot-canvas-batch/scripts/build_canvases.mjs --themes <root>/themes.json

ORIENTATION/DRILL_PER/RECENT_DAYS 等 env 见该 skill。近 90 天同主题会被自动去重。)

建完后取本次产出的 canvasId:

node ./scripts/latest_canvases.mjs --json

它读 topics-history/最新一次 run.json,并核对每个 canvas 的 images/ 是否真有图 (present:true)。只对 present 的 canvas 继续发布。

注意:hot-canvas-batch 跑完会关掉服务,且历史不存 url。发布阶段不需要服务在跑 ——导出脚本直接读 server/data/canvases/<id>/ 磁盘文件,与服务无关。

阶段 2 —— 导出 + 文案润色(可用 subagent 并行)

每个 canvas 互相独立、且都是纯磁盘操作(读画册、写导出包、改文案),所以这一阶段 可以并行。对每个 canvasId 派一个 subagent(general-purpose,在单条消息里并行发起):

每个 subagent 的任务:

  1. 跑导出脚本(仅标准库):
    # cwd in canvas-to-social skill root
    python3 ./scripts/export_canvas.py <canvasId> \
      --data-root /abs/path/to/app/server/data --limit 35
    
    脚本末尾打印 OUT_DIR=...(导出目录,含 images/01-..NN.png文案.md)。
  2. 文案润色(口语化):读 文案.md 的原始百科图说,改写为:
    • 标题 ≤ 20 字,要有钩子/悬念/数字。
    • 正文 ≤ 1000 字,口语化、有节奏、能引发互动;末尾用纯文本 #话题 #话题 带 3-6 个 相关话题标签。
    • 把改好的标题+正文写回导出目录下一个 发布文案.md(或回报给主流程)。
  3. subagent 用 SendMessage 把 {canvasId, OUT_DIR, 标题, 正文, 图片数} 回报给 main。

字数铁律来自 canvas-to-social/references/publishing-douyin.md:标题≤20、正文≤1000、图片≤35。

阶段 3 —— 多 tab 填充(串行,共享一个 Chrome)

发布要操作用户已登录的 Chrome,所有 tab 共享同一个 CDP 会话,无法真正并行—— 但可以把 N 条都填好、各占一个 tab,作为「图解世界」待发布分组,最后让用户逐个点发布。

前置:用户已在自己 Chrome 登录抖音;browser-harness CLI 可用(用法见 browser skill)。

对每个 canvas 的导出包,依次执行(细节严格按 canvas-to-social skill 中的 references/publishing-douyin.md 的第 1-7 步):

  1. new_tab("https://creator.douyin.com/creator-micro/content/upload?default-tab=3") —— 直接进发布图文页(比从首页找入口更稳)。wait_for_load() 后确认是上传页。
  2. upload_file("input[type=file]", sorted(images/*.png)) 上传(顺序 01..NN)。
  3. 标题(≤20):用 prototype value setter + 派发 input/change。
  4. 正文(≤1000):contenteditable 用 execCommand('insertText');话题写成纯文本 #词
  5. 背景音乐(必做):音乐入口卡片的真正可点元素是 .container-right-uW7Pj1/ .action-Q1y01k,用原生 .click() 打开抽屉(click_at_xy 常无效)。点之前先确保 上一步合集下拉已收起(否则 .semi-portal 浮层会盖住音乐入口,命中测试会返回 semi-select-option)。 抽屉打开后扫 ([\d.]+)万人使用按播放量取前 10 首热门候选, 再 random.choice 随机选一首(不要固定取第一名),hover 后点「使用」,读到「修改音乐」 即成功。批量发布时维护 used_songs 集合跳过已用歌,保证多条 BGM 各不相同。详见 canvas-to-social skill 中的 references/publishing-douyin.md 第 5 步。
  6. 合集:先选合集选音乐(避免下拉浮层挡住音乐入口)。用「不选择合集」文字定位 .semi-select 点开,存在「图解世界」就选,否则跳过(绝不自动新建)。
  7. 校验(读回标题字数/正文字数/图片数/合集名/音乐),定位「发布」按钮但不点

步骤顺序建议:上传图 → 标题 → 正文 →(先)合集 →(后)音乐 → 校验。把音乐放在 合集之后,能规避「合集下拉残留浮层挡住音乐入口」这个高频坑。

每个 tab 填完后保留打开,进入下一个 canvas 的新 tab。N 个全部填好后,向用户报告每个 tab 的状态清单,并提示:请逐个检查后自行点「发布」。

阶段 4 —— 收尾汇报

给用户一张总表:每条 = canvasId / 主题 / 图片数 / 标题 / 正文字数 / 合集 / tab 状态 (已就绪待发布)。明确说明:没有任何一条被自动发布,发布权在用户手里。


subagent 用法要点

  • 并行:仅阶段 2(导出+润色)派多个 subagent,单条消息多个 Agent 调用并发。 每个 subagent 拿到 canvasId + --data-root 绝对路径 + 字数限制 + 润色要求,自洽完成。
  • 串行:阶段 3(浏览器填充)不要派并行 subagent——多个 agent 抢同一个 Chrome CDP 会互相踩踏。由 main(或单个发布 subagent)顺序操作多个 tab。
  • subagent 是无状态的:prompt 里给全绝对路径、canvasId、字数上限、润色风格,别让它去 猜上下文。

常见坑

  • canvas 缺图:建册阶段 codebuddy planner 偶发 JSON 解析失败会让个别节点没图。 latest_canvases.mjsimageCount/present 能帮你筛掉空画册;导出 --limit 35 本就只取有图节点的 BFS 顺序。
  • 历史无 url、服务已关:发布不依赖服务,导出脚本读磁盘即可。要预览画册再另起服务。
  • 坐标漂移:浏览器步骤每次按文字/placeholder 重新查询元素,绝不跨步骤复用坐标 (见 canvas-to-social skill 中的 references/publishing-douyin.md 健壮性要点)。
  • 别让 subagent 碰发布:导出/润色可委托,浏览器填充和发布留在主线程顺序做,且永不 自动发布。
通过SMTP发送电子邮件,支持文本、HTML及文件内容。凭据从环境变量读取,默认使用163邮箱。适用于发送邮件、通知报告或附带文件内容的场景。
用户要求发送邮件 通过邮件交付通知或报告 需要将文件内容以邮件形式发送
.codebuddy/skills/send-email/SKILL.md
npx skills add imcuttle/flipbook-app --skill send-email -g -y
SKILL.md
Frontmatter
{
    "name": "send-email",
    "description": "Use when the user wants to send an email, deliver a notification\/report by email, or email a file's contents. Sends via SMTP using credentials from environment variables (SMTP_HOST\/PORT\/USER\/TOKEN). Defaults to the 163 mailbox configured in this environment."
}

send-email

Send email via SMTP. Credentials come from environment variables, never hardcoded.

Credentials (environment variables)

Var Meaning Example
SMTP_HOST SMTP server smtp.163.com
SMTP_PORT port — 465 = SSL, 587 = STARTTLS 465
SMTP_USER login user / default From imcuttle@163.com
SMTP_TOKEN authorization code / app password (NOT login password for 163/QQ)
SMTP_FROM optional, overrides From

Usage

python3 ./scripts/send_email.py \
  --to imcuttle@163.com \
  --subject "主题" \
  --body "正文文本"

Other body sources and options:

  • --body-file /path/to/body.txt — read body from a file
  • piped stdin: echo "正文" | ... send_email.py --to a@x.com --subject "Hi"
  • --html — treat body as HTML
  • --to / --cc / --bcc — repeatable for multiple recipients
  • --from — override the From address

Run python3 ./scripts/send_email.py --help for the full list.

Notes

  • Port 465 → SSL (SMTP_SSL); any other port → plain SMTP + STARTTLS.
  • Prints OK: sent from ... to ... via host:port on success; exits non-zero with an ERROR: line if a credential env var is missing.
  • Never echo SMTP_TOKEN; only read it from the environment.

Главная - Вики-сайт
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-07-08 18:21
浙ICP备14020137号-1 $Гость$