Skill v1.0.1
currentAutomated scan100/1003 files
version: "1.0.1" name: publish-zsxq-article description: Publish Markdown articles to Zsxq (知识星球) as drafts. Use when user wants to publish a Markdown file to Zsxq, or mentions "发布到知识星球", "星球文章", "zsxq article". Handles Markdown content input and saves as draft (never auto-publish).
Publish Zsxq Article
Publish Markdown content to Zsxq (知识星球) article editor in Markdown mode, saving as draft for user review before publishing.
Prerequisites
- Browser automation MCP (either one):
- Chrome DevTools MCP (
mcp__chrome-devtools__*) - Playwright MCP (
mcp__playwright__*) - User logged into Zsxq (知识星球)
Browser MCP Tool Mapping
This skill works with both Chrome DevTools MCP and Playwright MCP:
| Action | Chrome DevTools MCP | Playwright MCP | |
|---|---|---|---|
| Navigate | navigate_page | browser_navigate | |
| Take snapshot | take_snapshot | browser_snapshot | |
| Take screenshot | take_screenshot | browser_take_screenshot | |
| Click element | click | browser_click | |
| Fill text | fill | browser_type | |
| Upload file | upload_file | browser_file_upload | |
| Press key | press_key | browser_press_key | |
| Evaluate JS | evaluate_script | browser_evaluate |
Priority: Default to Playwright MCP. Use Chrome DevTools MCP only when Playwright MCP is unavailable.
Detection: At runtime, prefer mcp__playwright__browser_navigate. Fall back to mcp__chrome-devtools__navigate_page only if Playwright tools are not available.
Key URLs
- Login page:
https://wx.zsxq.com/login - Article editor:
https://wx.zsxq.com/article?groupId={groupId}
Group ID Resolution
The Zsxq group ID is required to navigate to the article editor (the groupId= URL parameter). Do not hardcode a default.
Before any navigation, resolve the group ID in this order:
- Skill argument — if the user invoked the skill with a group ID, use it.
- Environment variable — check
ZSXQ_GROUP_ID(optional, for users who publish repeatedly to the same group). - Prompt the user if neither is available:
> 请提供知识星球的 group ID(在星球 URL 里 groupId= 之后那串数字)。
Do not proceed to Step 2 (Navigate) without a resolved group ID.
Editor Interface
The Zsxq article editor has two modes:
Rich Text Mode (Default)
- Standard WYSIWYG editor with formatting toolbar
- Click "切换到 Markdown 模式 (内测)" to switch
Markdown Mode (Preferred)
- Uses Milkdown (ProseMirror-based WYSIWYG Markdown editor)
- Renders Markdown as formatted content (headings, bold, links, lists)
- Click "切换到富文本模式" to switch back
IMPORTANT: Content Insertion Method The Milkdown editor requires content to be inserted via paste event, NOT direct fill:
filltool → Content treated as plain text, Markdown NOT rendered- Paste event → Milkdown parses Markdown and renders it properly
Key Elements in Markdown Mode
- Title input: textbox "请在这里输入标题"
- Content area: ProseMirror editor (
.ProseMirrorclass) - Save button: "保存" (saves as draft)
- Preview button: "预览"
- Publish button: "发布" (DO NOT USE - always save as draft)
- Tags: "添加标签"
Main Workflow
Step 1: Prepare Content
Read the Markdown file and extract:
- Title: from YAML frontmatter
titlefield, or H1 header# Title, or filename - Content: Markdown body with the following stripped:
- YAML frontmatter (
---delimited block at the top) - H1 title line (already used as the article title)
- HTML comments (
<!-- ... -->) - Horizontal rules (`---`) — Milkdown's paste handler misparses
---, causing subsequent headings and formatting to break (e.g.,##rendered as bold**text instead of H2). Remove all---lines before pasting.
# Read the markdown filecat /path/to/article.md
Step 2: Navigate to Article Editor
# Navigate to the article editor with the resolved group ID (see Group ID Resolution above)navigate_page: https://wx.zsxq.com/article?groupId={groupId}
If not logged in, the page will redirect to login. Prompt user to log in manually:
请先登录知识星球,登录完成后告诉我。Login URL: https://wx.zsxq.com/login
Step 3: Switch to Markdown Mode
After page loads, check if already in Markdown mode by looking for "切换到富文本模式" text.
If in Rich Text mode (shows "切换到 Markdown 模式"):
- Click "切换到 Markdown 模式 (内测)"
- Confirm the dialog by clicking "确定"
// Check current modeconst switchBtn = document.querySelector('[class*="switch"]');if (switchBtn && switchBtn.innerText.includes('切换到 Markdown')) {// Need to switch to Markdown mode}
Step 4: Fill Title
- Find the title textbox with placeholder "请在这里输入标题"
- Click to focus
- Type the title
click: title textboxfill: title textbox with article title
Step 5: Insert Markdown Content (via Paste Event)
CRITICAL: Do NOT use `fill` tool - it inserts plain text without Markdown rendering.
Instead, use evaluate_script to simulate a paste event:
// Simulate paste event to trigger Milkdown's Markdown parsing() => {const markdownContent = `YOUR_MARKDOWN_CONTENT_HERE`;const editorEl = document.querySelector('.ProseMirror');if (!editorEl) return { error: 'Editor not found' };// Focus the editoreditorEl.focus();// Create and dispatch paste eventconst clipboardData = new DataTransfer();clipboardData.setData('text/plain', markdownContent);const pasteEvent = new ClipboardEvent('paste', {bubbles: true,cancelable: true,clipboardData: clipboardData});editorEl.dispatchEvent(pasteEvent);return { success: true, charCount: markdownContent.length };}
This method:
- Creates a ClipboardEvent with the Markdown content
- Dispatches it to the ProseMirror editor
- Milkdown's paste handler parses and renders the Markdown
Step 6: Add Tags (Optional)
- Click "添加标签"
- Enter tag text
- Confirm
Step 7: Save as Draft
IMPORTANT: Always save as draft, NEVER click "发布" (Publish)
- Click "保存" button to save as draft
- Verify save was successful
click: "保存" button
Step 8: Verify and Report
After saving:
- Check for success message or draft status
- Report to user:
草稿已保存。请在知识星球中预览并手动发布。Draft saved. Please review in Zsxq and publish manually.
Complete Example Flow
User: "把 /path/to/my-article.md 发布到知识星球"
1. Read /path/to/my-article.md- Extract title from frontmatter or H1- Strip frontmatter, H1 title, HTML comments, and horizontal rules (`---`)- Get cleaned content2. Navigate to https://wx.zsxq.com/article?groupId={resolved groupId}3. Check if logged in- If not, prompt user to login4. Switch to Markdown mode if needed- Click "切换到 Markdown 模式 (内测)"- Confirm dialog5. Fill title- Click title input- Use `fill` tool to set title text6. Insert content via paste event- Use `evaluate_script` to simulate paste event- This triggers Milkdown to parse and render Markdown7. Save as draft- Click "保存"8. Report success- "草稿已保存,请手动预览并发布"
Critical Rules
- NEVER click "发布" - Only save as draft using "保存"
- Always use Markdown mode - Switch if in Rich Text mode
- Check login status - Prompt user to login if needed
- Preserve original file - Never modify the source Markdown file
- Report completion - Tell user the draft is saved and needs manual review
- Resolve group ID first - Never hardcode a group ID. Resolve via skill argument,
ZSXQ_GROUP_IDenv var, or user prompt before any navigation (see Group ID Resolution) - Prefer Playwright MCP - Default to Playwright MCP; only use Chrome DevTools MCP when Playwright is unavailable
Troubleshooting
Markdown Not Rendering (Shows Raw Syntax)
If you see raw Markdown syntax like **bold** or [link](url) instead of rendered formatting:
- Cause: Content was inserted using
filltool instead of paste event - Solution: Use the
evaluate_scriptmethod to simulate a paste event (see Step 5)
The Milkdown editor only parses Markdown when content is pasted, not when directly set.
Horizontal Rules (---) Break Formatting
If headings appear as bold text with ** markers, or formatting is garbled after a --- line:
- Cause: Milkdown's paste handler misparses
---(horizontal rule), corrupting subsequent Markdown elements - Solution: Strip all
---lines from the content before pasting. The article can use headings for section separation instead.
Login Required
If page redirects or shows login prompt:
请先登录知识星球: https://wx.zsxq.com/login登录完成后告诉我。
Content Too Long
Zsxq has a 100,000 character limit. If content exceeds:
文章内容超过100000字符限制,请考虑拆分文章。
Switch Mode Dialog
When switching to Markdown mode, a confirmation dialog appears:
- Message: "确定要切换编辑器?当前内容将不会同步至新编辑器"
- Click "确定" to confirm
Editor Not Loading
If editor elements are not visible:
- Wait for page to fully load
- Take a new snapshot
- If still not loading, refresh the page
Element Reference
| Element | Selector/Identifier | Description | |
|---|---|---|---|
| Title input | textbox "请在这里输入标题" | Article title (max 60 chars) | |
| Content area | .ProseMirror (Milkdown editor) | Markdown content (max 100000 chars) | |
| Save button | "保存" | Save as draft | |
| Preview button | "预览" | Preview article | |
| Publish button | "发布" | DO NOT USE | |
| Mode switch | "切换到 Markdown 模式" / "切换到富文本模式" | Toggle editor mode | |
| Tags | "添加标签" | Add article tags | |
| Word count | "正文字数:X /100000" | Character counter |
Image Upload
Image upload works in both Rich Text mode and Markdown mode using the upload_file tool.
Prerequisites
- Check image file size first: if > 500KB, compress to WebP or reduce quality
- Use
ls -la /path/to/image.pngto check file size
Image Upload Workflow
Image upload works with the image button in both editor modes:
- Take snapshot to find the image button ref/uid
- Rich Text mode:
button "image" - Markdown mode:
generic description="Add image"
- Upload image
Chrome DevTools MCP: `` upload_file: uid: <image button uid> filePath: /path/to/image.png ``
Playwright MCP: `` browser_file_upload: ref: <image button ref> paths: ["/path/to/image.png"] ``
- Verify upload - take screenshot to confirm image appears in editor
Key Elements for Image Upload
| Mode | Image Button | Selector in Snapshot | |
|---|---|---|---|
| Rich Text | button "image" | button "image" | |
| Markdown | Add image | generic description="Add image" |
Example Image Upload (Markdown Mode)
# 1. Take verbose snapshot to find image buttontake_snapshot(verbose=true)# 2. Find "Add image" button (e.g., uid=26_59)# Look for: generic description="Add image"# 3. Upload image directly to the buttonupload_file:uid: 26_59 # (example uid for "Add image" button)filePath: /Users/user/Downloads/image.png# 4. Verify with screenshottake_screenshot
Example Image Upload (Rich Text Mode)
# 1. Take snapshot to find image buttontake_snapshot# 2. Find image button (e.g., uid=12_7)# Look for: button "image"# 3. Upload image to the buttonupload_file:uid: 12_7 # (example uid for image button)filePath: /Users/user/Downloads/image.png# 4. Verify with screenshottake_screenshot
Image Size Limits
- Maximum recommended: 500KB per image
- For larger images, compress first using tools like ImageMagick or sips:
```bash # Check size ls -la /path/to/image.png
# Compress if needed (macOS) sips -s format jpeg -s formatOptions 80 /path/to/image.png --out /path/to/image_compressed.jpg ```
Troubleshooting Image Upload
Image not appearing after upload:
- Take a fresh verbose snapshot to get correct uid for image button
- Verify the image file exists and is accessible
- Check the word count indicator - it should increase after successful upload
Finding the correct button uid:
- Use
take_snapshot(verbose=true)to see element descriptions - In Markdown mode, look for
generic description="Add image" - In Rich Text mode, look for
button "image"
Technical Details
The Zsxq article editor uses two different editors:
Rich Text Mode (Quill)
- Quill: A modern WYSIWYG editor
- Image upload: Works via
upload_filetool tobutton "image" - Toolbar: Standard formatting buttons including image
Markdown Mode (Milkdown)
- Milkdown: A plugin-driven WYSIWYG markdown editor
- ProseMirror: The underlying rich-text editing framework
- Paste handling: Milkdown intercepts paste events and parses Markdown content
- Image upload: Works via
upload_filetool togeneric description="Add image"
This is why the user's workflow via md.bytenote.net works - pasting from any source triggers Milkdown's Markdown parser, resulting in properly rendered content.