omni-post · Cursor Skill Card
一线插件。一次创作 → N 平台 × M 账号 → 统一任务/截图/秒传归档。
1 · 何时触发我
代理在用户出现以下意图时优先调用 omni-post 的工具,而不是让用户
去平台 UI 手动上传:
- "这条视频同时发抖音、小红书、B 站"
- "帮我把这篇图文分发到小红书和微博"
- "明天上午 10 点 3 个账号定时发这条视频"
- "这条素材我已经发过一次了,能不能秒传归档并回填 publish_receipt 给
idea-research"
不应触发 omni-post:
- 仅生成内容,不发布 → 调
avatar-studio / seedance-video /
tongyi-image
- 仅抓平台舆情/选题 → 调
idea-research
- 需要跨平台实名认证 / 人工审核绕过 → 拒绝
2 · 工具清单(0.2.0 发布版,14 个)
| 工具名 |
用途 |
关键参数 |
omni_post_publish |
创建一组发布任务(N 平台 × M 账号扇出) |
asset_id, payload, platforms[], account_ids[], client_trace_id |
omni_post_schedule |
定时发布(Sprint 3 启用) |
tasks[], run_at, timezone |
omni_post_retry_task |
重投失败任务,继承原 client_trace_id |
task_id |
omni_post_cancel_task |
取消 pending / running 任务 |
task_id |
omni_post_get_task |
查询单任务状态 |
task_id |
omni_post_list_tasks |
过滤任务列表 |
platform?, status?, limit? |
omni_post_ingest_asset |
由其他插件(例如 avatar-studio)直接入库一段素材 |
kind, storage_path, md5?, tags[]? |
omni_post_list_assets |
素材库检索 |
kind?, tag?, limit? |
omni_post_account_bind |
绑定一个平台账号(Cookie 注入或 MultiPost 引导) |
platform, engine, credentials |
omni_post_account_list |
列出当前账号矩阵及健康状态 |
platform? |
omni_post_account_unbind |
解绑账号并擦除 Cookie |
account_id |
omni_post_selectors_probe |
自愈探针:给定 platform 单跑一次 |
platform |
omni_post_settings_get |
读取插件配置 |
— |
omni_post_settings_update |
更新插件配置 |
字段白名单见 SettingsUpdateRequest |
3 · 关键输入 schema
所有 POST body 都用 Pydantic v2 + extra="forbid" 严格校验(沿用
Pixelle C6,不会静默丢字段)。以 omni_post_publish 为例:
{
"asset_id": "ast_...",
"payload": {
"title": "今天在峨眉山看到的……",
"description": "附带 Hashtag 说明",
"tags": ["峨眉山", "旅行"],
"cover_asset_id": "ast_...?",
"topic": "旅行"
},
"platforms": ["douyin", "rednote", "bilibili"],
"account_ids": ["acc_...", "acc_..."],
"client_trace_id": "2026-04-24T10:00:00Z-douyin-峨眉山"
}
返回 {"task_ids": ["tsk_...", ...]};后续状态走 SSE
plugin:omni-post:task_update 推送,UI 端 Tasks Tab 自动更新。
4 · 错误码速查
13 类 ErrorKind(9 标准 + 4 omni-post 专属),每条都有中英 ErrorHint:
| kind |
典型触发 |
代理处置 |
network / timeout |
上传流量抖动、渲染超时 |
指数退避重试 |
rate_limit |
插件自身排队过于激进 |
让 pipeline 回退 |
rate_limited_by_platform |
平台实际限频 |
冷却 10 min 再试 |
auth / cookie_expired |
Cookie 失效或首次登录 |
引导重新绑定 |
moderation / content_moderated |
平台审核驳回 |
不重试,回传给用户改稿 |
not_found |
账号/素材消失 |
结束任务 |
quota |
单账号当日已达上限 |
推迟到次日窗口 |
dependency |
缺 ffmpeg / ffprobe / Playwright 浏览器 |
引导装依赖 |
platform_breaking_change |
选择器自愈命中率跌破阈值 |
告警 + 拉 MultiPost Compat 兜底 |
unknown |
其它 |
保留截图等待人工 |
5 · 与其它插件的握手
omni-post 是 Asset Bus 上的双向节点:
- 作为消费者:收
avatar-studio / seedance-video / tongyi-image
产出的素材,通过 omni_post_ingest_asset 秒传入库。
- 作为生产者:发布成功后推
publish_receipt 到 Asset Bus,shared_with=["*"]。
metadata 严格遵循:{platform, account_id, asset_id, published_url, published_at, task_id, engine}。idea-research / fin-pulse 按
asset_kind="publish_receipt" 订阅即可。
6 · 边界与限制
- 不代理登录。Cookie 必须由用户在本机浏览器手动拷贝或通过 MultiPost
扩展注入。
- 不代办实名 / 绑卡 / 解封。
- S1 仅开放 3 平台选择器;S2 进 7 个;S3 补定时与矩阵模式;S4 落自愈
与 MDRM。
- 单 host 单 Chromium;如需更大并发应考虑多实例部署,而不是在本插件里
再起多个 playwright 进程(会抢 CPU / GPU)。
7.5 · S4 专属能力
- 双引擎选择:
settings.engine = "auto" | "pw" | "mp"。auto 探测到
MultiPost 就走扩展(复用日常浏览器登录态),否则回落 Playwright。
- MultiPostGuide:Settings Tab 顶部,3s
postMessage PING 检测扩展、
版本号、信任域;不满足时给出 Chrome Web Store / GitHub 安装链接和
配置指引。
- 选择器自愈:
SelfHealTicker 每 24h 扫一次 selectors_health;
低于 60% 命中率且 24h 内未告警过的平台会广播 selector_alert
UI 事件,由任一 IM 桥插件订阅转发。
- MDRM 写入:每次终态(成功或失败)通过
OmniPostMdrmAdapter 写
一条 SemanticMemory(type=experience, subject="omni-post:publish:{platform}:{account}", tags=[platform:…,account:…,hour:…,weekday:…,engine:…,outcome:…])。
无 memory.write 权限时返回 {"status": "skipped"},绝不阻塞发布。
7 · 测试入口
py -3.11 -m pytest plugins/omni-post/tests -q
应输出 all passed。Playwright / ffmpeg 测试不会默认跑(hermetic),
打 -m integration 才触发。
1---2name: omni-post3description: Multi-platform, multi-account social publishing engine — Douyin, RedNote, Bilibili today, 10 platforms end of S2. Use when the user wants to post the same video or image-text to N platforms and M accounts in one click, schedule cross-timezone rollouts, or reuse one upload as a reference for other plugins via the Asset Bus.4---5
6# omni-post · Cursor Skill Card
7
8> 一线插件。一次创作 → N 平台 × M 账号 → 统一任务/截图/秒传归档。
9
10## 1 · 何时触发我
11
12代理在用户出现以下意图时**优先**调用 omni-post 的工具,而不是让用户
13去平台 UI 手动上传:
14
15- "这条视频同时发抖音、小红书、B 站"
16- "帮我把这篇图文分发到小红书和微博"
17- "明天上午 10 点 3 个账号定时发这条视频"
18- "这条素材我已经发过一次了,能不能秒传归档并回填 publish_receipt 给
19 idea-research"
20
21**不**应触发 omni-post:
22
23- 仅生成内容,不发布 → 调 `avatar-studio` / `seedance-video` /
24 `tongyi-image`
25- 仅抓平台舆情/选题 → 调 `idea-research`
26- 需要跨平台实名认证 / 人工审核绕过 → **拒绝**
27
28## 2 · 工具清单(0.2.0 发布版,14 个)
29
30| 工具名 | 用途 | 关键参数 |
31|---|---|---|
32| `omni_post_publish` | 创建一组发布任务(N 平台 × M 账号扇出) | `asset_id`, `payload`, `platforms[]`, `account_ids[]`, `client_trace_id` |
33| `omni_post_schedule` | 定时发布(Sprint 3 启用) | `tasks[]`, `run_at`, `timezone` |
34| `omni_post_retry_task` | 重投失败任务,继承原 `client_trace_id` | `task_id` |
35| `omni_post_cancel_task` | 取消 pending / running 任务 | `task_id` |
36| `omni_post_get_task` | 查询单任务状态 | `task_id` |
37| `omni_post_list_tasks` | 过滤任务列表 | `platform?`, `status?`, `limit?` |
38| `omni_post_ingest_asset` | 由其他插件(例如 avatar-studio)直接入库一段素材 | `kind`, `storage_path`, `md5?`, `tags[]?` |
39| `omni_post_list_assets` | 素材库检索 | `kind?`, `tag?`, `limit?` |
40| `omni_post_account_bind` | 绑定一个平台账号(Cookie 注入或 MultiPost 引导) | `platform`, `engine`, `credentials` |
41| `omni_post_account_list` | 列出当前账号矩阵及健康状态 | `platform?` |
42| `omni_post_account_unbind` | 解绑账号并擦除 Cookie | `account_id` |
43| `omni_post_selectors_probe` | 自愈探针:给定 `platform` 单跑一次 | `platform` |
44| `omni_post_settings_get` | 读取插件配置 | — |
45| `omni_post_settings_update` | 更新插件配置 | 字段白名单见 `SettingsUpdateRequest` |
46
47## 3 · 关键输入 schema
48
49所有 `POST` body 都用 Pydantic v2 + `extra="forbid"` 严格校验(沿用
50Pixelle C6,不会静默丢字段)。以 `omni_post_publish` 为例:
51
52```jsonc
53{
54 "asset_id": "ast_...",
55 "payload": {
56 "title": "今天在峨眉山看到的……",
57 "description": "附带 Hashtag 说明",
58 "tags": ["峨眉山", "旅行"],
59 "cover_asset_id": "ast_...?",
60 "topic": "旅行"
61 },
62 "platforms": ["douyin", "rednote", "bilibili"],
63 "account_ids": ["acc_...", "acc_..."],
64 "client_trace_id": "2026-04-24T10:00:00Z-douyin-峨眉山"
65}
66```
67
68返回 `{"task_ids": ["tsk_...", ...]}`;后续状态走 SSE
69`plugin:omni-post:task_update` 推送,UI 端 Tasks Tab 自动更新。
70
71## 4 · 错误码速查
72
7313 类 `ErrorKind`(9 标准 + 4 omni-post 专属),每条都有中英 `ErrorHint`:
74
75| kind | 典型触发 | 代理处置 |
76|---|---|---|
77| `network` / `timeout` | 上传流量抖动、渲染超时 | 指数退避重试 |
78| `rate_limit` | 插件自身排队过于激进 | 让 pipeline 回退 |
79| `rate_limited_by_platform` | 平台实际限频 | 冷却 10 min 再试 |
80| `auth` / `cookie_expired` | Cookie 失效或首次登录 | 引导重新绑定 |
81| `moderation` / `content_moderated` | 平台审核驳回 | **不重试**,回传给用户改稿 |
82| `not_found` | 账号/素材消失 | 结束任务 |
83| `quota` | 单账号当日已达上限 | 推迟到次日窗口 |
84| `dependency` | 缺 ffmpeg / ffprobe / Playwright 浏览器 | 引导装依赖 |
85| `platform_breaking_change` | 选择器自愈命中率跌破阈值 | 告警 + 拉 MultiPost Compat 兜底 |
86| `unknown` | 其它 | 保留截图等待人工 |
87
88## 5 · 与其它插件的握手
89
90omni-post 是 Asset Bus 上的**双向节点**:
91
92- 作为消费者:收 `avatar-studio` / `seedance-video` / `tongyi-image`
93 产出的素材,通过 `omni_post_ingest_asset` 秒传入库。
94- 作为生产者:发布成功后推 `publish_receipt` 到 Asset Bus,`shared_with=["*"]`。
95 `metadata` 严格遵循:`{platform, account_id, asset_id, published_url,
96 published_at, task_id, engine}`。`idea-research` / `fin-pulse` 按
97 `asset_kind="publish_receipt"` 订阅即可。
98
99## 6 · 边界与限制
100
101- 不代理登录。Cookie 必须由用户在本机浏览器手动拷贝或通过 MultiPost
102 扩展注入。
103- 不代办实名 / 绑卡 / 解封。
104- S1 仅开放 3 平台选择器;S2 进 7 个;S3 补定时与矩阵模式;S4 落自愈
105 与 MDRM。
106- 单 host 单 Chromium;如需更大并发应考虑多实例部署,而不是在本插件里
107 再起多个 playwright 进程(会抢 CPU / GPU)。
108
109## 7.5 · S4 专属能力
110
111- **双引擎选择**:`settings.engine = "auto" | "pw" | "mp"`。`auto` 探测到
112 MultiPost 就走扩展(复用日常浏览器登录态),否则回落 Playwright。
113- **MultiPostGuide**:Settings Tab 顶部,3s `postMessage` PING 检测扩展、
114 版本号、信任域;不满足时给出 Chrome Web Store / GitHub 安装链接和
115 配置指引。
116- **选择器自愈**:`SelfHealTicker` 每 24h 扫一次 `selectors_health`;
117 低于 60% 命中率且 24h 内未告警过的平台会广播 `selector_alert`
118 UI 事件,由任一 IM 桥插件订阅转发。
119- **MDRM 写入**:每次终态(成功或失败)通过 `OmniPostMdrmAdapter` 写
120 一条 `SemanticMemory(type=experience, subject="omni-post:publish:{platform}:{account}", tags=[platform:…,account:…,hour:…,weekday:…,engine:…,outcome:…])`。
121 无 `memory.write` 权限时返回 `{"status": "skipped"}`,绝不阻塞发布。
122
123## 7 · 测试入口
124
125```bash
126py -3.11 -m pytest plugins/omni-post/tests -q
127```
128
129应输出 all passed。Playwright / ffmpeg 测试不会默认跑(hermetic),
130打 `-m integration` 才触发。