# 半自动发布 SOP（小红书创作中心 · 图文笔记）

用途："帮我把这篇发出去""发布到小红书"。把 `note-compose.md` 的草稿 + 用户提供的本地图片，
填进小红书创作页（creator.xiaohongshu.com），**填完截图给用户核对就停**。

## 铁律（最高优先级，先读再动手）

> **发布是不可逆的外发操作。Agent 绝不自动点击「发布」按钮——发布那一下永远由用户亲手点。**

- Agent 只做到：传图 → 填标题/正文/标签 → `screenshot` 给用户核对 → **停下交回用户**。
- 即使用户说"帮我发了"，也只填到位、截图核对，把"点发布"留给用户本人——这一条不因用户催促而放宽。
- 遇验证码/登录失效/风控（`300012` 等）**立即停下告诉用户**，绝不自动绕验证（沿用 `runtime-rules.md`）。
- 单步重试 ≤ 1；连续失败就停报，别在同一处死磕。

## 前置（缺了就先问用户）

1. **完整草稿**：标题 + 正文 + 标签（`note-compose.md` 的 `【发布草稿】`，用户已确认）。
2. **本地图片绝对路径**：小红书发图文**必须先有图、文字表单才会出现**，所以图是前置。多张用逗号分隔。

## 流程（选择器已对真实登录态 DOM 校正 ✅ 2026-06-17）

1. **环境/登录**：`browser{action:"status"}`；主站没登录就 `browser{action:"login", url:"https://www.xiaohongshu.com"}` 让用户扫码（登录态持久，通常一次）。**先确认主站 `xiaohongshu.com` 已登录**——创作平台靠它做 SSO（见下）。
2. **进创作发布页**：`browser{action:"open", url:"https://creator.xiaohongshu.com/publish/publish?source=official"}`。
   - **坑（已校正）**：创作平台子域 `creator.xiaohongshu.com` **单独鉴权**——直接导航首帧常落 `…/login?redirectReason=401`，但只要主站已登录，**2–4 秒内会自动 SSO 跳回 `/publish/publish`**。所以 open 后 `browser{action:"wait", ms:3000}` 再 `read url` 核对已回到 `/publish/publish`；若仍停在 `/login` 则是主站登录也失效了 → 停下让用户重新扫码。
   - 旧的 `…/publish/publish.html` 会 **404**，别用。
3. **切到「上传图文」**：页面默认是**「上传视频」** tab（此时 file input 只收视频）。必须先点图文 tab：`browser{action:"act", kind:"click", ref:"<上传图文 tab>"}`。tab 是 `div.creator-tab`、内含 `span.title`（文本「上传图文」）——CSS 选不中文本，用 `snapshot` 拿该 tab 的 @ref 再点，或 `eval` 里 `[...document.querySelectorAll("div.creator-tab")].find(e=>e.textContent.trim()==="上传图文").click()`。点对后 file input 的 `accept` 会变成 `.jpg,.jpeg,.png,.webp`。
4. **传图**：`browser{action:"act", kind:"upload", ref:"input.upload-input", text:"<图片绝对路径，多张逗号分隔>"}`。
   - file input = `input.upload-input`（**原样传选择器、不走 @ref 归一**；详见 `agent-browser` 技能「上传文件」段）。
   - 传完 `browser{action:"wait", ms:3000}` 等图上传完、编辑表单出现，再继续。
5. **填标题**：`browser{action:"act", kind:"fill", ref:"input[placeholder*='标题']", text:"<标题>"}`（placeholder「填写标题会有更多赞哦」，`fill` 实测可用）。
6. **填正文**：正文是 **TipTap/ProseMirror 富文本**，选择器 `div.tiptap.ProseMirror`（contenteditable）。**实测 `fill` 与 `type` 都能写入**：一次性写正文用 `kind:"fill"`；要在已有内容后追加用 `kind:"type"`（fill 会替换、type 追加）。
7. **加标签**：正文下方标签区输 `#话题`（输 `#` 后从联想列表点选）。
8. **截图核对**：`browser{action:"screenshot"}` 把整页回给用户。
9. **停**：明确告诉用户"已填好，请你核对后**亲手点发布**"。底部有「暂存离开」「发布」两个按钮——**到此为止，绝不点发布。**

## 已校正选择器速查（2026-06-17 真实发布页）

| 用途 | 选择器 | 备注 |
|---|---|---|
| 上传图文 tab | `div.creator-tab`（文本「上传图文」） | 默认在「上传视频」，必须先切 |
| file input | `input.upload-input` | 切到图文后 `accept` 变图片；upload 选择器原样传 |
| 标题输入 | `input[placeholder*='标题']` | `fill` 可用 |
| 正文编辑器 | `div.tiptap.ProseMirror` | ProseMirror；`fill`/`type` 均可 |
| 发布按钮 | 底部文案「发布」（旁「暂存离开」） | **仅截图核对定位，绝不程序化点击** |

> 小红书改版会让选择器失效。抽不到就**如实报"没抽到"**，别硬填、别编。失效时 `snapshot`/`eval` 看真实 class 再更新本表（同 `eval-patterns.md` 纪律）。
