Communitygithub.com

chemny/cmm-content-factory

Self-contained AI content factory for topic sourcing, writing, visuals, typesetting, short video, and draft publishing across 10 cmm-* skills.

Compatible conClaude Code~Codex CLI~Cursor
npx skills add chemny/cmm-content-factory

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentación

CMM Publishing

cmm-publishing is the publishing and draft-routing layer in the CMM content factory.

It consumes content_package, optional visual_package, and optional video_package, then produces a publish_package with platform support, metadata, asset mapping, approval gates, and execution route. After explicit confirmation, an approved backend can create a draft or browser-review state.

Boundary

Use this skill for:

  • Assembling a publish_package.
  • Deciding whether the target should be draft_box, browser_review, or schedule_plan, manual_upload, or unsupported.
  • Preparing platform metadata, asset mapping, and checklist output.
  • Running backend preflight before platform execution.
  • Choosing a safer fallback when the preferred backend is unavailable.
  • Selecting WeChat, X, Weibo, Xiaohongshu, or social scheduling workflows only as approved execution backends.
  • Recording publishing gaps for platforms not yet supported.

Do not use this skill to:

  • Write the content draft.
  • Generate images or render videos.
  • Click Publish, Post, 发布, or any externally visible submit action by default.

Publish Boundary

This skill assembles a publish_package and prepares drafts / manual-upload instructions. Built-in publish paths: WeChat draft box API (scripts/wechat_draft.py), WeChat browser draft fallback (scripts/wechat_browser_draft.mjs), X (scripts/x_publish.mjs), Weibo (scripts/weibo_publish.mjs), and Douyin (scripts/douyin_publish.py). Browser paths default to fill-only: the assistant fills the content and stops before final public publishing, and the user clicks publish themselves in the browser (the assistant does not auto-click, even on confirmation — see Confirmation Rules). Live auto-publish to platforms not yet built in (e.g. Xiaohongshu live-fill) remains an optional plugin, never routed to by default. If a platform-specific gap appears, record it in platform_gaps and update CMM contracts or docs.

Input

Preferred input:

content_package:
  platform: ""
  format: ""
  title: ""
  body_markdown: ""
  summary: ""
  sources_used: []
  publish_notes: ""
  status: draft

visual_package:
  asset_paths: []
  status: draft

video_package:
  render_path: ""
  cover_path: ""
  publish_copy: ""
  status: draft

Read references/publish-package-contract.md for exact output fields. Read references/publishing-method.md for support matrix, metadata, approval rules, backend preflight, and fallback behavior. Read references/wechat-quality-gate.md before WeChat draft creation; use templates/wechat-layout-package-template.md for the WeChat layout handoff.

Workflow

  1. Validate available packages.
  2. Resolve target platform.
  3. Choose target mode:
    • draft_box: API or platform draft when supported.
    • browser_review: browser opens with content filled, user reviews manually.
    • schedule_plan: planning/calendar output only.
    • unsupported: platform gap recorded.
  4. Build publish_package.
  5. Add metadata, checklist, platform gaps, and approval requirements.
  6. Run preflight for the selected backend before platform execution:
    • runtime dependencies
    • credentials or logged-in state
    • API/IP allowlist constraints where detectable
    • required cover/image/video assets
    • backend capability gaps
  7. If preflight fails, either choose a documented fallback or set publish_status: blocked with a concrete platform_gaps item. When both "repair preferred backend" and "fallback backend" are plausible, do not switch automatically. Report the reason, whether any draft/assets were created, present the decision options, and wait for the user to choose.
  8. Ask for explicit confirmation before invoking any platform skill unless the user already requested draft/browser/manual preparation in the current turn. For WeChat long-form outputs coming from CMM Content Factory, the local preview gate outranks same-turn draft intent: do not invoke the WeChat draft-box backend until the user has seen and confirmed the rendered preview and then confirmed draft-box creation.
  9. Route to an approved backend only after confirmation or same-turn draft intent where no stricter preview gate applies.
  10. Stop before any final public post unless the user explicitly confirms the final publish action in the same turn.

Routing

Default output is a publish package + draft / manual-upload instructions. X, Weibo, Douyin, and WeChat draft are built-in (review-before-publish by default). The right-hand column marks platforms whose live publish still needs the optional live-publish plugin; without the relevant runtime, follow the manual-upload path.

PlatformCMM target (default)Live publish (built-in / optional plugin)
WeChat Official Accountdraft_box via built-in scripts/wechat_draft.py; browser fallback via scripts/wechat_browser_draft.mjs when API/IP allowlist blocks— (draft/fill paths are built-in)
X / Twitterbuilt-in browser publish via scripts/x_publish.mjs (raw CDP, spawns native Chrome, persistent login, default review-before-publish); see references/x-publish.md. Falls back to manual upload.— (built-in)
Weibobuilt-in browser publish via scripts/weibo_publish.mjs (raw CDP, spawns native Chrome, persistent login, default review-before-publish); see references/weibo-publish.md. Falls back to manual upload.— (built-in)
Xiaohongshu / Rednote image notepublish package + manual uploadoptional browser-publish plugin
Xiaohongshu / Rednote video notepublish package + manual uploadoptional browser-publish plugin
Cross-platform calendarschedule_plan (plan only)optional scheduler plugin
Douyinbuilt-in browser publish via sau (scripts/douyin_publish.py, default --review-before-publish); see references/douyin-publish.md. Falls back to manual_upload if sau unavailable.— (built-in)
Bilibilimanual_upload or unsupportednone until verified

publish_package

publish_package:
  platform: ""
  target: draft_box
  title: ""
  body_ref: ""
  body_markdown: ""
  asset_refs: []
  video_ref: ""
  metadata: {}
  approval_status: pending
  publish_status: not_started
  route: ""
  approval_gate:
    draft_creation: pending
    final_publish: required_same_turn
  backend_preflight: []
  fallback_history: []
  readiness_gate: {}
  checklist: []
  platform_gaps: []
  external_result: {}

Confirmation Rules

  • Building publish_package does not require confirmation.
  • If the user explicitly asks for a platform draft, draft box, browser review, or manual-upload package in the current turn, set approval_status: target_intent_recorded until any stricter upstream preview gate is satisfied. After preview confirmation and explicit draft-box/browser confirmation, set approval_status: approved_for_draft and allow draft preparation.
  • Invoking a browser/API/platform skill requires explicit confirmation unless the current user request already clearly asks for draft/browser/manual preparation and no stricter preview gate applies.
  • Fill-only by default — the user clicks the final publish button themselves. For every browser-driven platform, the assistant fills the draft/composer/creator backend, stops at the publish button, and hands the open browser back to the user to publish. The assistant does not click the final publish button by default, even when the user confirms — the publish click is the user's action in the browser. (Rationale: an async submit / re-render at publish time has corrupted posts before, e.g. body text dropped on click.) The assistant fills, then screenshots or reports state for the user to review and publish.
  • --auto-publish / --submit and any auto-click switch are used only when the user, in the current turn, explicitly asks for automatic publishing; otherwise always stop at the publish button.
  • Never use --submit or click final publish buttons by default.
  • If a routed legacy skill has a stricter confirmation rule, follow the stricter rule.

Readiness Gate

GateRequirement
content_readyDraft exists and is not blocked.
asset_readyRequired cover/images/video are present or gap is explicit.
metadata_readyTitle, summary, tags, cover, and account/platform notes are prepared where relevant.
approval_readyDraft creation and final publish approvals are separated.
platform_supportedPlatform route is supported, manual, or explicitly unsupported.

Platform Notes

WeChat

  • Prefer draft-box behavior.
  • Covers are required for many article flows.
  • API/IP allowlist or browser login may be required.
  • Preflight API credentials and IP allowlist before doing full API draft work when possible.
  • If API fails with IP allowlist or token permission errors, fall back to the built-in browser route (scripts/wechat_browser_draft.mjs) when Chrome/login requirements pass.
  • Browser draft creation may not set the cover image through all backends. If the selected backend cannot confirm cover insertion, record an asset_gap and include cover path in checklist.

X

  • Built-in publish via scripts/x_publish.mjs (CMM-native, raw CDP, zero npm deps — uses Node ≥21 built-in WebSocket). Spawns native Chrome with a persistent profile (~/.cmm/chrome-x); the first run prompts a one-time x.com login (plain browser, so Google/X SSO is not blocked), reused thereafter. No stored credentials. --cdp URL can attach to an already-running debug-port Chrome.
  • Text is injected via CDP Input.insertText (real keyboard input: writes X's Draft.js EditorState so it survives re-render; execCommand('insertText') only touched the DOM and got wiped on publish — see references/x-publish.md). Needs the tab in front + a real click to focus. Media via CDP DOM.setFileInputFiles.
  • Fill-only: fill the composer, stop at the Post button; the user clicks Post themselves in the browser (--auto-publish only on explicit same-turn request).
  • See references/x-publish.md. Falls back to manual_upload if Chrome/debug-port/login is unavailable.

Weibo

  • Built-in publish via scripts/weibo_publish.mjs (CMM-native, raw CDP, zero npm deps). Spawns native Chrome with a persistent profile (~/.cmm/chrome-weibo); first run prompts a one-time weibo.com login. No stored credentials.
  • Fills the home composer <textarea> via CDP Input.insertText; images/videos (≤18 total) via CDP DOM.setFileInputFiles.
  • Fill-only: fill the composer, stop at the Send button; the user clicks Send themselves in the browser (--auto-publish only on explicit same-turn request).
  • See references/weibo-publish.md. Falls back to manual_upload if Chrome/debug-port/login is unavailable.

Xiaohongshu / Rednote

Preflight 检查(发布前必做)

项目限制
标题≤ 20 字
正文(去掉末尾话题标签行后)≤ 950 字(平台上限 1000,留安全边距)
图片数量1–9 张
图片格式jpg / png / webp,单张 ≤ 32MB

发布流程(图文笔记,已验证可用)

Step 1 — 直接导航到上传图文页

https://creator.xiaohongshu.com/publish/publish?from=menu&target=image

不要通过「发布笔记」下拉菜单点击,直接用 URL 跳转。

Step 2 — 核对账号

get_page_textjavascript_tool 读页面右上角账号名,确认是目标账号后再继续。账号不对让用户先切换,不要继续填写内容。

Step 3 — 上传图片

当前限制:Chrome 扩展 file_upload 工具只允许上传会话已共享的路径,本地 Documents 目录不在范围内。 现行操作:通知用户从 Finder(提前 open 图片目录)手动将图片拖入上传区,按顺序(封面在前)。 待解方案:在 Claude 桌面应用设置里将 ~/.cmm/uploads/ 加入 connected folders,生图流水线自动 cp 到该目录后可全自动上传。

Step 4 — 填写标题

find 定位标题 input(placeholder: "填写标题会有更多赞哦"),用 computer.typeform_input 填入。

Step 5 — 填写正文

正文区是 contenteditable div,用 javascript_tool 注入:

const div = document.querySelectorAll('[contenteditable="true"]')[0];
div.focus();
document.execCommand('selectAll');
document.execCommand('insertText', false, bodyText);

话题标签直接写在正文末尾(#话题 格式),小红书会自动解析。 注入完成后用 javascript_tool 读取页面字符计数器(X/1000)确认字数正确。

Step 6 — 停在发布按钮前

所有内容填完后停止,不点「发布」。告知用户内容已就绪,由用户自行确认并点击发布。

平台限制记录

  • 无内置发布脚本,不支持 API draft box。
  • 图片上传路径限制(见 Step 3)为当前已知 gap,记录在 platform_gaps
  • Final public publish 必须用户同步确认,不得代为点击。

Douyin (built-in) and Bilibili

  • Do not pretend final public publishing is complete without confirmation.
  • Douyin: built-in browser publish via sau (see references/douyin-publish.md, scripts/douyin_publish.py). Preflight gates: account selected, login/cookie valid, video/image + title/tags prepared. Default --review-before-publish (fill then stop at the publish button; the user clicks publish themselves in the open browser — do not auto-click even on confirmation). If sau is unavailable, fall back to manual_upload with a complete package.
  • Keep generated content/assets ready for manual upload even when login is not ready.
  • For Bilibili, output target: manual_upload when a complete manual package can be prepared; otherwise output target: unsupported.
  • Include a platform_gaps item explaining missing login, missing account, unsupported backend, or manual-upload requirements.

Stop Conditions

Stop and ask before:

  • Calling platform APIs.
  • Opening browser automation for logged-in platforms.
  • Uploading images or videos.
  • Clicking any final publish/post button.
  • Scheduling external posts.

Skills relacionados