Skill: gd269438407/xhs-daily-publisher (version 0.1.0)

--- name: xhs-auto-publisher description: 小红书自动化内容生产与发布助手。通过对话收集账号定位（领域/人设/视觉偏好/发布节奏），自动完成「热点选题 → 9 图文案 → HTML 视觉模板 → 高清图片渲染 → 浏览器自动发布 → 定时任务调度」全链路，最终保留"用户手动点发布"一步防封号。支持随时通过对话调整视觉风格、文案语气、选题方向。触发关键词：小红书、xhs、自动发布、自媒体、日更、9 图、数字人、每日速报、起号、作品集、批量生产、账号运营、图文生成。 agent_created: true --- # 小红书自动化内容生产与发布助手 ## 这个 Skill 是什么 **一套端到端的小红书日更自动化工作流。** 不是单点工具，是把「选题 → 内容 → 发布 → 优化」4 个环节打通成可循环运行的流水线。用户只需给出账号定位，Skill 会自动生成可发布的 9 图图文包，并在本机用浏览器自动打开发布页等用户点最后一下。 **关键设计哲学**： - **先跑通再扩能力**：不追求一次性完美，先建最小闭环（选题+文案+图+半自动发布），再扩展视频、抖音、数据回流 - **半自动发布**：最后"点发布"必须人工，降低封号风险（尤其新号前 7 天） - **持久化 profile + cookies**：首次扫码后永久免登 - **视觉模板化**：HTML + Puppeteer 渲染，一次写好 CSS，每天只换文字就能出 9 图 ## 何时使用此 Skill 当用户表达以下意图时，主动调用： - "我想做小红书自媒体 / 起号 / 日更" - "帮我自动发小红书" - "做一个 AI 内容账号 / 资讯号 / 速报号" - "我想通过 AI 做自媒体作品集 / 简历素材" - "每天自动生成小红书内容" - 已有类似项目要接手优化 **不适用**： - 只做抖音 / B站 / 公众号（本 skill 聚焦小红书，但架构可迁移） - 需要真人出镜的"生活 vlog"类内容（不适合全 AI 生产） - 超高垂直专业领域需要人工写稿审稿（本 skill 面向资讯/工具/速报类） ## 完整执行流程（7 步） ### Step 1｜收集定位（对话式） 通过 AskUserQuestion 收集 6 个关键字段，没有的字段给默认值，别卡住用户： | 字段 | 问题 | 默认值 | |---|---|---| | 领域 | 你想做什么领域的账号？ | 「AI 资讯」 | | 频道名/昵称 | 账号叫什么？ | 让用户自定 | | 受众 | 写给谁看？新手/进阶/专业人士？ | 「泛关注 AI 的打工人」 | | 发布节奏 | 日更/周 3/周 5？每天几点发？ | 每日早 8:35 | | 视觉风格 | 严肃研究风 / 爽文资讯风 / 简约极客风？ | 研究风（Aki 风：黑底白卡+宋体+红竖线+黄高亮） | | 数据源 | 中文国内源 / 英文外网 / 中英混合？ | 国内中文源（机器之心、36kr、CSDN、腾讯新闻） | **收集后必须确认一次**：把字段做成摘要给用户确认，不要直接开跑。 ### Step 2｜初始化项目目录 ``` {workspace}/ ├─ output/ # 每日内容包 │ └─ YYYY-MM-DD/ │ ├─ digest.md # 选题+文案 │ ├─ slides.html # 9 图源 HTML │ └─ images/ # 9 张 jpg ├─ scripts/ │ ├─ render_slides.js # HTML→图渲染器 │ └─ publish_xhs.js # 发布机器人 ├─ templates/ │ ├─ slides_template.html # 视觉模板（可复用） │ └─ config.json # 定位配置 ├─ .auth/ # 登录态 + 持久 profile（不进 git） │ ├─ xhs_cookies.json │ └─ chrome_profile/ └─ README.md # 给用户看的 3 分钟上手指南 ``` 把模板文件从 skill 目录复制过去： - `templates/slides_template.html` → 用户 output 目录 - `scripts/render_slides.js`, `scripts/publish_xhs.js` → 用户 scripts 目录 ### Step 3｜选题生成 调用 WebSearch 抓取当日所选领域热点（5-8 条候选），按"热度 + 争议度 + 算法友好度"3 维打分，选出： - 1 条主 topic（做 9 图深度版） - 1-2 条快讯（点缀在 06 海外线 或 07 时事速览页） **红线硬编码**（Skill 里留给用户自定义补充列表）： - 避开与用户所在公司冲突的产品 - 避开用户在职客户真名 - 新号前 7 天避 A 股上市公司敏感话题 输出 `output/YYYY-MM-DD/digest.md`（含选题打分表 + 小红书标题 + 正文 800 字 + 10 标签 + 9 图文案）。 ### Step 4｜生成 HTML 模板 根据 Step 1 选定的视觉风格，从 `templates/slides_template.html` 生成当日 `slides.html`。9 页结构： 1. 封面（标题/副标/日期/插图） 2. 导语（引文/背景铺垫） 3. 01 主角（核心事件） 4. 02 对照组（对比细节） 5. 03 为什么重要（意义解读） 6. 04 海外线 / 快讯（点缀） 7. 05 读图方式（辅助理解） 8. 06 记住这句话（金句） 9. 07 关注 CTA（@用户名 + 明日预告） **视觉风格预设**（skill 内置 3 套，用户选一套或自定义）： - **研究风（默认）**：黑背板 + 白卡片 + 思源宋体 Black + 红色左竖线 + 黄色马克笔高亮 + 灰底引用框 - **爽文风**：纯色大色块 + 思源黑体 Black + 大号中文数字 + 红/黄反差 - **极客风**：白底 + 等宽字体 + 单色（#111/#e63946）+ 代码块风格引用 ### Step 5｜渲染图片 ```bash node scripts/render_slides.js ``` 用 Puppeteer 无头模式把 HTML 渲染为 2160×2880 jpg（deviceScaleFactor=2），输出到 `output/YYYY-MM-DD/images/`。 ### Step 6｜更新并启动发布脚本 - 修改 `scripts/publish_xhs.js` 的 IMAGES_DIR / POST_TITLE / POST_BODY 为当日内容 - 启动脚本（非阻塞）：用户本机弹出 Chromium → 自动跳发布页 → 上传 9 图 → 填标题 → 填正文 → 停在发布页 - 告知用户："内容已填好，请在浏览器里点『发布』" **关键技术细节**（必须这么做，踩过的坑）： - `userDataDir: .auth/chrome_profile` 持久化，权限永久记住 - `context.overridePermissions` 预授权 notifications/clipboard，屏蔽弹窗 - 真实 UA + `ignoreDefaultArgs: ['--enable-automation']` 绕风控 - 监听 SIGINT/SIGTERM/SIGHUP + `browser.on('disconnected')` 优雅退出 - 30s setInterval keep-alive 防 macOS 杀僵尸进程 - 首次扫码成功后 saveCookies 到 `.auth/xhs_cookies.json` ### Step 7｜调度定时任务 调用 `automation_update` 创建 recurring automation： - 频率：用户在 Step 1 选定 - RRULE 示例：`FREQ=DAILY;BYHOUR=8;BYMINUTE=35;BYSECOND=0` - prompt 内容：让明日自动化按 Step 3-6 执行，最终把浏览器停在发布页 ### Step 8（可选）｜优化循环 发布 48 小时后，引导用户： 1. 回到这里说"看下昨天数据" 2. Skill 询问笔记链接或手动输入关键指标（播放、点赞、评论、粉丝增长） 3. 根据数据给建议： - 完播率 < 30%：前 3 页钩子太弱，下一期强化封面冲突 - 互动率 < 2%：结尾 CTA 不够，优化第 9 页 - 无粉丝增长但有流量：简介/昵称不匹配当下内容 ## 用户交互模式 Skill 触发后按顺序： 1. **第 1 轮**：简短自我介绍 + AskUserQuestion 收集 6 字段（一次问完，不要来回问） 2. **第 2 轮**：展示配置摘要，请用户确认 3. **第 3 轮**：一次性完成"建目录 + 复制模板 + 跑 Step 3-6"，最终告知"浏览器已在等你点发布" 4. **后续轮次**：按用户需求微调（改风格/改选题/看数据），不要每次都重跑全流程 **交互原则**： - 能用默认值不问用户 - 用户说"换风格"时，只重渲染图片，不重跑选题 - 用户说"不满意文案"时，只重生成 digest，不重跑视觉 ## 资源文件清单 本 skill 目录下包含： - `SKILL.md`（本文件） - `templates/slides_template.html`：默认视觉模板（研究风） - `scripts/render_slides.js`：渲染器 - `scripts/publish_xhs.js`：发布机器人（v3 持久 profile 版） - `templates/config.schema.json`：定位配置 schema - `assets/style-research.html`：研究风完整示例 - `assets/style-punchy.html`：爽文风完整示例 - `assets/style-geek.html`：极客风完整示例 ## 技术依赖 - Node.js ≥ 22（用户环境自带 managed 版本） - Puppeteer（一般已在 node workspace 里） - 系统：macOS（Linux/Windows 需改路径） - Chromium：Puppeteer 安装时附带 ## 合规与安全 - 发布最后一步必须人工点击（新号前 7 天硬规则） - cookies 和 profile 保存在用户项目的 .auth/ 目录，不上传云端、不进 git - 不代表用户发任何内容，所有发布动作由用户最终确认 - 视觉模板不抄袭任何具体博主，风格为"风格类别"层级（研究风/爽文风/极客风） ## 常见问题 **Q: 用户说"我不会写代码"怎么办？** A: 本 skill 设计前提就是用户不写代码，所有命令由 skill 调用 Bash 执行。用户只需要：① 对话回答 6 个问题 ② 扫码 1 次 ③ 每天点一下"发布"。 **Q: 视觉风格用户不满意？** A: 别换 HTML 架构，只调 CSS 颜色/字体/间距。改完让 skill 重跑 render_slides.js 即可。 **Q: 如何扩展到抖音？** A: 基于本 skill 的文案生成部分，增加 TTS 生成 + 数字人视频合成 + 抖音浏览器自动化。这是本 skill 的 V2 路线，当前 V1 专注小红书。 **Q: 封号风险？** A: 保留人工点发布 + 持久 profile + 真实 UA + 发布时间带轻微随机 ±5 分钟，综合下来与真人操作难以区分。

path: README.md
content: # xhs-auto-publisher

**小红书自动化内容生产与发布助手** · User-level Skill for WorkBuddy

## 一句话介绍

对话式配置账号定位 → 每天自动完成「热点选题 + 9 图文案 + 视觉渲染 + 浏览器自动发布」，你只需扫码 1 次、每天点一下「发布」。

## 典型使用场景

- AI 资讯 / 工具速报 / 科技财经类账号起号
- 想做小红书作品集证明 AI 工程化能力
- 已有日更计划但每天手工耗时 2-3 小时，想降到 30 秒

## 调用方式

在任意对话里说以下任一句，Skill 会被自动触发：

- "帮我做一个小红书自动化账号"
- "我要用 AI 每天自动发小红书"
- "/skill xhs-auto-publisher"

## 交互流程

1. **第一轮**：Skill 问你 6 个字段（领域/昵称/受众/发布时间/视觉风格/数据源），能默认就默认
2. **第二轮**：展示配置摘要，确认后一次性打通全流程
3. **之后**：每天指定时间浏览器自动弹出发布页，你点一下「发布」
4. **随时**：说"换个风格"、"看下数据"、"改一下文案语气"即可微调

## 可选视觉风格

| 预设 | 调性 | 示意 |
|---|---|---|
| `research` | 研究笔记风（黑底白卡+宋体+红竖线+黄高亮+灰引用） | 深度/理性/高知 |
| `punchy` | 爽文资讯风（纯色大色块+黑体大字+强反差） | 快餐/流量/情绪 |
| `geek` | 极客简约风（白底+等宽字体+单色+代码块引用） | 工程师/工具党 |
| `custom` | 自定义 | 你给描述，Skill 出 |

## 输出结构（用户项目目录）

```
project/
├─ output/
│   └─ YYYY-MM-DD/
│       ├─ digest.md    # 选题+文案
│       ├─ slides.html  # 9 图源
│       └─ images/      # 9 张 2160×2880 jpg
├─ scripts/             # 从 skill 复制过来
├─ .auth/               # 登录态 + profile（gitignore）
└─ README.md
```

## 核心技术细节

- **Puppeteer + 持久化 profile**：权限永久记住、反检测参数齐全
- **HTML + CSS 渲染 9 图**：一次写模板，每天只换文字
- **WorkBuddy automation**：调度每日定时任务
- **半自动发布**：最后一步人工点发布，防封号（新号前 7 天硬规则）

## 合规要求

- 用户必须提供自己的小红书账号（不代表用户做任何不合规发布）
- cookies 和 profile 只保存在用户本机项目目录
- 不抄袭具体博主风格，仅定义"风格类别"


path: scripts/publish_xhs.js
content: /**
 * 小红书自动发布机器人 · 通用模板
 * 由 xhs-auto-publisher skill 生成
 *
 * 使用说明：
 *   1. 修改 CONFIG 里的 WORKSPACE / POST_TITLE / POST_BODY / IMAGES_DIR
 *   2. 运行：node publish_xhs.js
 *   3. 首次会打开浏览器让你扫码登录小红书创作者中心
 *   4. 之后免登，自动完成上传图+填文案，停在发布页等你点"发布"
 */

const puppeteer = require('puppeteer');
const fs = require('fs');
const path = require('path');

// ============ 配置区 ============
const CONFIG = {
  WORKSPACE: process.env.XHS_WORKSPACE || process.cwd(),
  // 图片目录（内含 01.jpg ~ 09.jpg，最多 18 张）
  IMAGES_DIR: process.env.XHS_IMAGES_DIR || path.join(process.cwd(), 'output/images'),
  IMAGE_COUNT: parseInt(process.env.XHS_IMAGE_COUNT || '9', 10),
  POST_TITLE: process.env.XHS_POST_TITLE || '【请在 publish_xhs.js 里设置标题】',
  POST_BODY: process.env.XHS_POST_BODY || '【请在 publish_xhs.js 里设置正文】',
};
// =============================

const STATE_FILE = path.join(CONFIG.WORKSPACE, '.auth/xhs_cookies.json');
const USER_DATA_DIR = path.join(CONFIG.WORKSPACE, '.auth/chrome_profile');
const IMAGES = Array.from({ length: CONFIG.IMAGE_COUNT }, (_, i) =>
  path.join(CONFIG.IMAGES_DIR, String(i + 1).padStart(2, '0') + '.jpg')
);

const sleep = ms => new Promise(r => setTimeout(r, ms));
const ensureDir = d => { if (!fs.existsSync(d)) fs.mkdirSync(d, { recursive: true }); };

async function loadCookies(page) {
  if (!fs.existsSync(STATE_FILE)) return false;
  try {
    const cookies = JSON.parse(fs.readFileSync(STATE_FILE, 'utf8'));
    if (!cookies.length) return false;
    await page.setCookie(...cookies);
    return true;
  } catch (e) { return false; }
}

async function saveCookies(page) {
  ensureDir(path.dirname(STATE_FILE));
  const cookies = await page.cookies('https://creator.xiaohongshu.com', 'https://www.xiaohongshu.com');
  fs.writeFileSync(STATE_FILE, JSON.stringify(cookies, null, 2));
}

function registerGracefulShutdown(browser, page) {
  let closing = false;
  const shutdown = async (sig) => {
    if (closing) return; closing = true;
    console.log(`\n↩ 收到 ${sig}，优雅关闭...`);
    try { if (page && !page.isClosed()) await saveCookies(page); } catch {}
    try { if (browser && browser.isConnected()) await browser.close(); } catch {}
    process.exit(0);
  };
  ['SIGINT', 'SIGTERM', 'SIGHUP'].forEach(s => process.on(s, () => shutdown(s)));
}

(async () => {
  console.log('\n========== 小红书自动发布 ==========\n');
  console.log('标题：' + CONFIG.POST_TITLE);
  console.log('图片目录：' + CONFIG.IMAGES_DIR);
  console.log('图片数量：' + CONFIG.IMAGE_COUNT + '\n');

  // 校验图片存在
  for (const img of IMAGES) {
    if (!fs.existsSync(img)) {
      console.error('✗ 找不到图片:', img);
      process.exit(1);
    }
  }

  ensureDir(USER_DATA_DIR);
  ensureDir(path.dirname(STATE_FILE));

  const browser = await puppeteer.launch({
    headless: false,
    defaultViewport: null,
    userDataDir: USER_DATA_DIR,
    ignoreDefaultArgs: ['--enable-automation'],
    args: [
      '--no-sandbox',
      '--disable-setuid-sandbox',
      '--disable-blink-features=AutomationControlled',
      '--disable-infobars',
      '--disable-notifications',
      '--disable-popup-blocking',
      '--disable-features=TranslateUI',
      '--disable-ipc-flooding-protection',
      '--disable-background-timer-throttling',
      '--disable-backgrounding-occluded-windows',
      '--disable-renderer-backgrounding',
      '--no-first-run',
      '--no-default-browser-check',
      '--window-size=1440,960',
    ],
  });

  const pages = await browser.pages();
  const page = pages[0] || await browser.newPage();
  await page.setViewport({ width: 1440, height: 900 });
  registerGracefulShutdown(browser, page);

  const ctx = browser.defaultBrowserContext();
  await ctx.overridePermissions('https://creator.xiaohongshu.com', ['notifications', 'clipboard-read', 'clipboard-write']);
  await ctx.overridePermissions('https://www.xiaohongshu.com', ['notifications', 'clipboard-read', 'clipboard-write']);

  await page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36');

  await loadCookies(page);

  console.log('→ 打开发布页');
  await page.goto('https://creator.xiaohongshu.com/publish/publish?source=official', {
    waitUntil: 'domcontentloaded',
    timeout: 60000,
  });
  await sleep(3000);

  if (page.url().includes('/login')) {
    console.log('⚡ 请扫码登录小红书创作者中心（本次登录后永久免登）');
    try {
      await page.waitForFunction(() => !location.href.includes('/login'), { timeout: 300000 });
      console.log('✓ 登录成功');
      await saveCookies(page);
      await sleep(2000);
      if (!page.url().includes('/publish')) {
        await page.goto('https://creator.xiaohongshu.com/publish/publish?source=official', { waitUntil: 'domcontentloaded' });
        await sleep(3000);
      }
    } catch (e) {
      console.log('✗ 5 分钟内未完成登录，退出');
      await browser.close();
      process.exit(1);
    }
  } else {
    await saveCookies(page);
  }

  await sleep(4000);

  // 切图文 tab
  try {
    await page.evaluate(() => {
      const tab = Array.from(document.querySelectorAll('*'))
        .find(el => el.children.length === 0 && (el.innerText || '').trim() === '上传图文');
      if (tab) tab.click();
    });
    await sleep(1500);
  } catch {}

  console.log('→ 上传' + CONFIG.IMAGE_COUNT + '张图');
  let input = await page.$('input[type="file"]');
  if (!input) {
    await page.waitForSelector('input[type="file"]', { timeout: 20000 }).catch(() => {});
    input = await page.$('input[type="file"]');
  }
  if (!input) {
    console.log('✗ 找不到上传入口。浏览器保持打开，可手动操作。');
    await new Promise(() => {});
  }
  await input.uploadFile(...IMAGES);
  await sleep(12000);

  console.log('→ 填标题');
  await page.evaluate((title) => {
    const cand = document.querySelector('input[placeholder*="标题"]')
              || document.querySelector('textarea[placeholder*="标题"]')
              || document.querySelector('input[placeholder*="填写标题"]');
    if (!cand) return false;
    const nat = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')
             || Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value');
    nat.set.call(cand, title);
    cand.dispatchEvent(new Event('input', { bubbles: true }));
    cand.dispatchEvent(new Event('change', { bubbles: true }));
    return true;
  }, CONFIG.POST_TITLE);

  console.log('→ 填正文');
  await page.evaluate(() => {
    const ed = document.querySelector('div[contenteditable="true"]');
    if (ed) ed.focus();
  });
  await sleep(600);
  await page.keyboard.type(CONFIG.POST_BODY, { delay: 5 });

  console.log('\n✓ 全部填完！请在浏览器中点"发布"按钮，然后关闭窗口。\n');

  browser.on('disconnected', () => {
    console.log('↩ 浏览器已关闭，脚本退出');
    process.exit(0);
  });
  setInterval(() => {}, 30000);
})().catch(err => {
  console.error('\n✗ 错误：', err.message);
  console.error(err.stack);
  process.exit(1);
});


path: scripts/render_slides.js
content: /**
 * 9 图 HTML → 高清 JPG 渲染器
 * 由 xhs-auto-publisher skill 生成
 *
 * 使用：node render_slides.js <slides.html> <output_dir>
 *   slides.html 里需要有 #s1, #s2, ..., #s9 共 9 个 slide 容器
 *   渲染分辨率：1080×1440 @ 2x = 2160×2880
 */

const puppeteer = require('puppeteer');
const path = require('path');
const fs = require('fs');

const htmlPath = process.argv[2] || path.join(process.cwd(), 'slides.html');
const outDir   = process.argv[3] || path.join(process.cwd(), 'images');
const pageCount = parseInt(process.env.SLIDE_COUNT || '9', 10);

(async () => {
  if (!fs.existsSync(htmlPath)) {
    console.error('✗ 找不到 HTML:', htmlPath);
    process.exit(1);
  }
  if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true });

  const browser = await puppeteer.launch({
    headless: 'new',
    args: ['--no-sandbox', '--disable-setuid-sandbox', '--font-render-hinting=none'],
  });
  const page = await browser.newPage();
  await page.setViewport({ width: 1080, height: 1440, deviceScaleFactor: 2 });
  await page.goto('file://' + path.resolve(htmlPath), { waitUntil: 'networkidle0' });
  await page.evaluate(() => document.fonts.ready);
  await new Promise(r => setTimeout(r, 800));

  for (let i = 1; i <= pageCount; i++) {
    const el = await page.$('#s' + i);
    if (!el) { console.log('⚠ 跳过 #s' + i + '（未找到）'); continue; }
    const out = path.join(outDir, String(i).padStart(2, '0') + '.jpg');
    await el.screenshot({ path: out, type: 'jpeg', quality: 94 });
    console.log('✓', out);
  }
  await browser.close();
  console.log('done.');
})();


path: templates/config.schema.json
content: {
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "xhs-auto-publisher · 账号配置",
  "type": "object",
  "required": ["channel_name", "domain", "visual_style", "post_time"],
  "properties": {
    "channel_name": {
      "type": "string",
      "description": "频道名/昵称，会出现在封面与 CTA 页",
      "examples": ["Zea 说 AI", "AI 每日速报"]
    },
    "domain": {
      "type": "string",
      "description": "内容领域",
      "examples": ["AI 资讯", "职场效率", "AI 工具", "科技财经"]
    },
    "audience": {
      "type": "string",
      "description": "目标受众",
      "default": "泛关注该领域的打工人"
    },
    "visual_style": {
      "type": "string",
      "enum": ["research", "punchy", "geek", "custom"],
      "description": "视觉风格预设",
      "default": "research"
    },
    "post_time": {
      "type": "string",
      "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$",
      "description": "每日触发时间，HH:MM",
      "default": "08:35"
    },
    "post_frequency": {
      "type": "string",
      "enum": ["daily", "weekdays", "weekly"],
      "default": "daily"
    },
    "data_sources": {
      "type": "array",
      "items": { "type": "string" },
      "description": "优先抓取的数据源白名单",
      "default": ["机器之心", "36kr", "CSDN", "腾讯新闻", "网易科技", "央广科技"]
    },
    "blocked_topics": {
      "type": "array",
      "items": { "type": "string" },
      "description": "必须避开的话题/公司名",
      "default": []
    },
    "language": {
      "type": "string",
      "enum": ["zh", "en", "bilingual"],
      "default": "zh"
    }
  }
}


path: templates/slides_template.html
content: <!--
  小红书 9 图视觉模板 · 研究风（Aki 风）
  占位符用 {{FIELD}} 表示，由 Skill 在生成时替换。

  必需占位：
    {{CHANNEL_NAME}}    频道名，例如 "Zea 说 AI"
    {{DATE_STR}}        日期字符串，例如 "2026-05-04" 或 "5 月 4 日"
    {{COVER_TITLE}}     封面主标题（不超过 10 字，会显示为巨大衬线字）
    {{COVER_SUB}}       封面副标题（红色，不超过 15 字）
    {{COVER_HINT}}      封面下方 hint 文字，例如 "今日 AI 圈发生了什么"
    {{INTRO_LEAD}}      导语引文（斜体，15-30 字）
    {{INTRO_BODY}}      导语正文 HTML（可含 <b> <span class="hl"> <span class="rk">）
    {{P01_TITLE}}       01 主角标题
    {{P01_SUB}}         01 副标
    {{P01_BULLETS}}     01 要点列表（<li>...</li> 多条）
    {{P01_QUOTE}}       01 引用框 HTML
    ...同理 P02 P03 P04 P05 P06 P07
    {{CTA_HANDLE}}      @用户名，用于最后一页
    {{NEXT_PREVIEW}}    明日预告 HTML
  可选占位：
    {{COVER_SVG}}       封面 SVG 插图（不传则留白）
-->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>{{CHANNEL_NAME}} · {{DATE_STR}}</title>
<style>
  @import url('https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@500;700;900&family=Noto+Sans+SC:wght@400;500;700;900&display=swap');
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body { font-family: 'Noto Sans SC', 'PingFang SC', system-ui, sans-serif; background: #0b0b0b; }
  .slide { width: 1080px; height: 1440px; background: #0b0b0b; display: flex; justify-content: center; align-items: flex-start; padding: 70px 60px; page-break-after: always; }
  .card { width: 100%; height: 100%; background: #ffffff; border-radius: 22px; padding: 90px 76px; position: relative; overflow: hidden; display: flex; flex-direction: column; }
  .pn { position: absolute; top: 52px; right: 52px; background: #e8e8e8; color: #5a5a5a; font-size: 26px; font-weight: 500; padding: 8px 20px; border-radius: 22px; letter-spacing: 1px; }
  .h1 { font-family: 'Noto Serif SC', serif; font-weight: 900; font-size: 88px; line-height: 1.1; color: #111; padding-left: 30px; border-left: 8px solid #e63946; margin-bottom: 28px; }
  .h1 .num { color: #111; font-weight: 900; margin-right: 18px; }
  .sub { font-size: 40px; color: #8a8a8a; font-weight: 500; margin-bottom: 52px; line-height: 1.4; }
  .serif-title { font-family: 'Noto Serif SC', serif; font-weight: 900; color: #111; line-height: 1.12; }
  .underline { height: 6px; background: #111; margin: 36px 0 40px; }
  .quote { background: #f3f3f3; border-radius: 14px; padding: 38px 44px; font-size: 40px; color: #2a2a2a; line-height: 1.55; font-weight: 500; margin: 30px 0; }
  .quote.italic { font-style: italic; color: #444; border-left: 8px solid #e63946; border-radius: 0 14px 14px 0; padding-left: 34px; }
  ul.bl { list-style: none; padding: 0; margin: 12px 0; }
  ul.bl li { position: relative; padding-left: 36px; font-size: 42px; line-height: 1.65; color: #1a1a1a; margin-bottom: 18px; font-weight: 500; }
  ul.bl li::before { content: ""; width: 12px; height: 12px; border-radius: 50%; background: #1a1a1a; position: absolute; left: 0; top: 28px; }
  .rk { color: #e63946; font-weight: 900; }
  .hl { background: linear-gradient(180deg, transparent 45%, #ffe265 45%, #ffe265 92%, transparent 92%); padding: 0 4px; font-weight: 900; color: #111; }
  b, strong { color: #111; font-weight: 900; }

  /* 封面特殊样式 */
  .s1 .card { background: #f6eed8; padding: 0; align-items: center; justify-content: center; }
  .cover-wrap { width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; padding: 70px 50px 60px; position: relative; }
  .cover-title { font-family: 'Noto Serif SC', serif; font-weight: 900; font-size: 88px; color: #111; margin-bottom: 18px; letter-spacing: 2px; text-align: center; }
  .cover-pn { position: absolute; top: 60px; right: 60px; background: rgba(0,0,0,.15); color: #fff; font-size: 26px; padding: 8px 20px; border-radius: 22px; }
  .ice { flex: 1; width: 100%; display: flex; justify-content: center; align-items: center; margin-top: 10px; }
  .ice svg { width: 100%; height: auto; max-height: 1050px; }
  .cover-brand { position: absolute; bottom: 44px; right: 60px; font-size: 24px; color: rgba(0,0,0,.45); font-weight: 500; letter-spacing: 3px; }
</style>
</head>
<body>

<div class="slide s1" id="s1"><div class="card"><div class="cover-wrap">
  <div class="cover-pn">1 / 9</div>
  <div class="cover-title">{{COVER_TITLE}}</div>
  <div style="font-family: 'Noto Serif SC'; font-weight:700; font-size:56px; color:#e63946; letter-spacing:4px; margin-bottom: 20px;">{{COVER_SUB}}</div>
  <div style="font-size:30px; color:#555; letter-spacing:3px; margin-bottom: 40px;">{{DATE_STR}} · {{COVER_HINT}}</div>
  <div class="ice">{{COVER_SVG}}</div>
  <div class="cover-brand">{{CHANNEL_NAME}}</div>
</div></div></div>

<div class="slide s2" id="s2"><div class="card">
  <div class="pn">2 / 9</div>
  <div class="serif-title" style="font-size:92px;">{{P02_TITLE}}</div>
  <div class="underline"></div>
  <div class="quote italic" style="font-size:44px;">{{INTRO_LEAD}}</div>
  <div style="font-size:38px; line-height:1.75; color:#1a1a1a; margin-top: 36px;">{{INTRO_BODY}}</div>
</div></div>

<div class="slide s3" id="s3"><div class="card">
  <div class="pn">3 / 9</div>
  <div class="h1"><span class="num">01</span> {{P03_TITLE}}</div>
  <div class="sub">{{P03_SUB}}</div>
  <ul class="bl">{{P03_BULLETS}}</ul>
  <div class="quote">{{P03_QUOTE}}</div>
</div></div>

<div class="slide s4" id="s4"><div class="card">
  <div class="pn">4 / 9</div>
  <div class="h1"><span class="num">02</span> {{P04_TITLE}}</div>
  <div class="sub">{{P04_SUB}}</div>
  <ul class="bl">{{P04_BULLETS}}</ul>
  <div class="quote italic">{{P04_QUOTE}}</div>
</div></div>

<div class="slide s5" id="s5"><div class="card">
  <div class="pn">5 / 9</div>
  <div class="h1"><span class="num">03</span> {{P05_TITLE}}</div>
  <div class="sub">{{P05_SUB}}</div>
  <div style="font-size:40px; color:#444; margin-top: 40px; line-height:1.8; font-weight:500;">{{P05_BODY}}</div>
  <div class="quote">{{P05_QUOTE}}</div>
</div></div>

<div class="slide s6" id="s6"><div class="card">
  <div class="pn">6 / 9</div>
  <div class="h1"><span class="num">04</span> {{P06_TITLE}}</div>
  <div class="sub">{{P06_SUB}}</div>
  <ul class="bl">{{P06_BULLETS}}</ul>
  <div class="quote italic">{{P06_QUOTE}}</div>
</div></div>

<div class="slide s7" id="s7"><div class="card">
  <div class="pn">7 / 9</div>
  <div class="h1"><span class="num">05</span> {{P07_TITLE}}</div>
  <div class="sub">{{P07_SUB}}</div>
  <ul class="bl">{{P07_BULLETS}}</ul>
  <div class="quote">{{P07_QUOTE}}</div>
</div></div>

<div class="slide s8" id="s8"><div class="card">
  <div class="pn">8 / 9</div>
  <div class="h1"><span class="num">06</span> 记 住 这 句 话</div>
  <div class="sub">如果今天只带走一句话</div>
  <div style="flex:1; display:flex; flex-direction:column; justify-content:center;">
    <div style="font-family:'Noto Serif SC'; font-weight:900; font-size:74px; color:#111; line-height:1.35;">{{PUNCHLINE}}</div>
    <div style="font-size:38px; color:#666; margin-top: 60px; line-height:1.7; font-weight:500;">{{PUNCHLINE_FOOT}}</div>
  </div>
</div></div>

<div class="slide s9" id="s9"><div class="card">
  <div class="pn">9 / 9</div>
  <div class="h1"><span class="num">07</span> 每 日 速 报</div>
  <div class="sub">关注不错过</div>
  <div style="flex:1; display:flex; flex-direction:column; justify-content:center;">
    <div style="font-family:'Noto Serif SC'; font-weight:900; font-size:100px; color:#e63946; text-align:center; margin-bottom: 30px;">{{CTA_HANDLE}}</div>
    <div style="font-size:32px; color:#666; text-align:center; margin-bottom: 80px;">关 注 · 不 错 过</div>
    <div class="quote" style="text-align:center; font-size:34px;">
      <b>明 日 预 告</b><br>
      <span style="font-size:42px; color:#111;">{{NEXT_PREVIEW}}</span>
    </div>
  </div>
</div></div>

</body>
</html>


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)