From 01coder-skills
Publishes Markdown files/URLs to X (Twitter) Articles editor with rich text conversion. Handles cover images and converts unsupported elements (tables, mermaid diagrams, deep headers) to images based on Premium/Premium+ subscription.
npx claudepluginhub sugarforever/01coder-agent-skills --plugin 01coder-skillsThis skill uses the workspace's default tool permissions.
Publish Markdown content to X (Twitter) Articles editor, preserving formatting with rich text conversion. Automatically handles X Premium limitations by converting unsupported elements to images.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Publish Markdown content to X (Twitter) Articles editor, preserving formatting with rich text conversion. Automatically handles X Premium limitations by converting unsupported elements to images.
This skill is inspired by and based on wshuyi/x-article-publisher-skill. Thank you to the original author for the foundational work.
IMPORTANT: Before processing the article, ask the user about their X subscription type if not already known.
Before publishing, I need to know your X subscription type to handle formatting correctly:
1. **X Premium** - Basic tier ($8/month)
2. **X Premium+** - Plus tier ($16/month)
Which subscription do you have? (Premium / Premium+)
For Chinese users:
在发布之前,我需要了解您的 X 订阅类型以正确处理格式:
1. **X Premium** - 基础版 ($8/月)
2. **X Premium+** - 高级版 ($16/月)
您使用的是哪个版本?(Premium / Premium+)
Once the user answers, remember their subscription type for the rest of the session. Don't ask again unless they explicitly want to change it.
| Feature | X Premium | X Premium+ |
|---|---|---|
H1 headers (#) | Title only | Title only |
H2 headers (##) | Yes | Yes |
H3+ headers (###, etc.) | No | Yes |
| Markdown tables | No | Yes |
| Mermaid diagrams | No | No (not supported by X) |
| Code blocks | Blockquotes | Blockquotes |
| Bold, italic, links | Yes | Yes |
| Lists | Yes | Yes |
| Blockquotes | Yes | Yes |
| Images | Yes | Yes |
X Premium (Basic):
X Premium+ (Plus):
pip install Pillow pyobjc-framework-Cocoa markdownpip install Pillow pywin32 clip-util markdownLocated in ~/.claude/skills/publish-x-article/scripts/:
Parse Markdown and extract structured data:
python parse_markdown.py <markdown_file> [--output json|html] [--html-only]
Returns JSON with: title, cover_image, content_images (with block_index for positioning), html, total_blocks
Copy image or HTML to system clipboard:
# Copy image (with optional compression)
python copy_to_clipboard.py image /path/to/image.jpg [--quality 80]
# Copy HTML for rich text paste
python copy_to_clipboard.py html --file /path/to/content.html
Convert Mermaid diagrams and Markdown tables to PNG images via diagramless.xyz API:
node ~/.claude/skills/diagram-to-image/scripts/diagram-to-image.mjs /tmp/table.md -o /tmp/table.png
node ~/.claude/skills/diagram-to-image/scripts/diagram-to-image.mjs /tmp/diagram.mmd -o /tmp/diagram.png --theme ocean
Before publishing, scan the Markdown for unsupported elements and convert them to images.
# Check the markdown file for unsupported elements
cat /path/to/article.md
Look for:
###, ####, etc.| characters forming table structure ```mermaidWhen a table is detected:
# 1. Extract table to temp file
cat > /tmp/table.md << 'TABLE_EOF'
| Column 1 | Column 2 | Column 3 |
|----------|----------|----------|
| Data 1 | Data 2 | Data 3 |
TABLE_EOF
# 2. Convert to image via diagramless.xyz API
node ~/.claude/skills/diagram-to-image/scripts/diagram-to-image.mjs /tmp/table.md -o /tmp/table-001.png
# 3. Replace table in markdown with image reference
# 
When a mermaid block is detected:
# 1. Extract mermaid to temp file
cat > /tmp/diagram.mmd << 'MERMAID_EOF'
flowchart TD
A[Start] --> B[Process]
B --> C[End]
MERMAID_EOF
# 2. Convert to image via diagramless.xyz API
node ~/.claude/skills/diagram-to-image/scripts/diagram-to-image.mjs /tmp/diagram.mmd -o /tmp/diagram-001.png
# 3. Replace mermaid block in markdown with image reference
# 
Goal: Preserve the article's logical structure and readability while working within X Premium's H2-only limitation.
Guidelines for the AI:
When you encounter H3, H4, or deeper headers in a Premium user's article, think about what the author intended:
If the header introduces a distinct subtopic under a section, convert it to bold text as a paragraph opener. This maintains visual hierarchy without breaking X's formatting.
If the header is a major section that happens to be H3, consider promoting it to H2 — but only if this doesn't create a flat, meaningless structure. The article should still flow logically.
If there's a deep hierarchy (H2 → H3 → H4), flatten thoughtfully:
Preserve meaning over structure. A header like ### Why This Matters might become a bold lead-in: **Why does this matter?** followed by the content. Use your judgment.
Read the content. If an H3 header is just "Example" or "Note", it might work better as a blockquote or inline emphasis rather than a standalone bold line.
The goal is not mechanical conversion — it's creating an article that reads well on X while honoring the author's intent.
Before publishing, read through the article and prepare it for X:
Understand the article's structure — Read it first. What are the main sections? How does the author use headers to organize ideas?
Handle tables and mermaid diagrams — These need to become images. Extract each one, convert to PNG, and note where they should be inserted.
Adapt headers for the subscription tier:
Create the modified markdown — Save your adapted version to a temp file, ready for parsing.
The goal is an article that reads naturally on X, not a mechanically transformed document.
Strategy: "先文后图后分割线" (Text First, Images Second, Dividers Last)
For articles with images and dividers, paste ALL text content first, then insert images and dividers at correct positions using block index.
目标: 最小化操作之间的等待时间,实现流畅的自动化体验。
大多数浏览器操作(click, type, press_key 等)都会在返回结果中包含页面状态。不要在每次操作后单独调用 browser_snapshot,直接使用操作返回的页面状态即可。
❌ 错误做法:
browser_click → browser_snapshot → 分析 → browser_click → browser_snapshot → ...
✅ 正确做法:
browser_click → 从返回结果中获取页面状态 → browser_click → ...
只在以下情况使用 browser_wait_for:
textGone="正在上传媒体")不要使用 browser_wait_for 来等待按钮或输入框出现 - 它们在页面加载完成后立即可用。
当两个操作没有依赖关系时,可以在同一个消息中并行调用多个工具:
✅ 可以并行:
- 填写标题 (browser_type) + 复制HTML到剪贴板 (Bash)
- 解析Markdown生成JSON + 生成HTML文件
❌ 不能并行(有依赖):
- 必须先点击create才能上传封面图
- 必须先粘贴内容才能插入图片
每个浏览器操作返回的页面状态包含所有需要的元素引用。直接使用这些引用进行下一步操作:
# 理想流程(每步直接执行,不额外等待):
browser_navigate → 从返回状态找create按钮 → browser_click(create)
→ 从返回状态找上传按钮 → browser_click(上传) → browser_file_upload
→ 从返回状态找应用按钮 → browser_click(应用)
→ 从返回状态找标题框 → browser_type(标题)
→ 点击编辑器 → browser_press_key(Meta+v)
→ ...
在开始浏览器操作之前,先完成所有准备工作:
这样浏览器操作阶段可以连续执行,不需要中途停下来处理数据。
First, read the article. Understand what it's about, how it's structured, and what the author is trying to communicate.
IMPORTANT: Never modify the user's original file. If adaptations are needed:
/tmp/article_adapted.md or alongside the original as article_for_x.md)I've adapted your article for X Premium. Here's what changed:
- Converted 2 tables to images
- Restructured 3 H3 headers to bold text for better flow
Original preserved: /path/to/article.md
Adapted version: /path/to/article_for_x.md
This ensures the user can review the changes and keeps their original work intact.
Ask yourself:
Create a modified version of the markdown that will work within Premium's limitations while preserving readability.
Ask yourself:
# Tables → PNG (auto-detected as table)
node ~/.claude/skills/diagram-to-image/scripts/diagram-to-image.mjs /tmp/table-1.md -o /tmp/table-1.png
# Mermaid → PNG (auto-detected as mermaid)
node ~/.claude/skills/diagram-to-image/scripts/diagram-to-image.mjs /tmp/diagram-1.mmd -o /tmp/diagram-1.png
Replace these elements in the markdown with image references, positioning them where the original element was.
Use parse_markdown.py to extract all structured data:
python ~/.claude/skills/publish-x-article/scripts/parse_markdown.py /path/to/modified_article.md
Output JSON:
{
"title": "Article Title",
"cover_image": "/path/to/first-image.jpg",
"content_images": [
{"path": "/tmp/table-1.png", "block_index": 5, "after_text": "context..."},
{"path": "/tmp/mermaid-1.png", "block_index": 12, "after_text": "another context..."}
],
"dividers": [
{"block_index": 7, "after_text": "context before divider..."},
{"block_index": 15, "after_text": "another context..."}
],
"html": "<p>Content...</p><h2>Section</h2>...",
"total_blocks": 45
}
Key fields:
block_index: The image/divider should be inserted AFTER block element at this index (0-indexed)total_blocks: Total number of block elements in the HTMLafter_text: Kept for reference/debugging only, NOT for positioningdividers: Array of divider positions (markdown --- must be inserted via X's menu, not HTML <hr>)Save HTML to temp file for clipboard:
python parse_markdown.py modified_article.md --html-only > /tmp/article_html.html
browser_navigate: https://x.com/compose/articles
重要: 页面加载后会显示草稿列表,不是编辑器。需要:
browser_snapshot 检查页面状态# 1. 导航到页面
browser_navigate: https://x.com/compose/articles
# 2. 获取页面快照,找到 create 按钮
browser_snapshot
# 3. 点击 create 按钮(通常 ref 类似 "create" 或带有 create 标签)
browser_click: element="create button", ref=<create_button_ref>
# 4. 现在编辑器应该打开了,可以继续上传封面图等操作
注意: 不要使用 browser_wait_for text="添加标题" 来等待页面加载,因为这个文本只有在点击 create 后才出现,会导致超时。
If login needed, prompt user to log in manually.
Copy HTML to system clipboard using Python, then paste:
# Copy HTML to clipboard
python ~/.claude/skills/publish-x-article/scripts/copy_to_clipboard.py html --file /tmp/article_html.html
Then in browser:
browser_click on editor textbox
browser_press_key: Meta+v
This preserves all rich text formatting (H2, bold, links, lists).
关键改进: 使用 block_index 精确定位,而非依赖文字匹配。
粘贴 HTML 后,编辑器中的内容结构为一系列块元素(段落、标题、引用等)。每张图片的 block_index 表示它应该插入在第 N 个块元素之后。
block_index 点击对应的块元素For each content image (from content_images array):
# 1. Copy image to clipboard (with compression)
python ~/.claude/skills/publish-x-article/scripts/copy_to_clipboard.py image /path/to/img.jpg --quality 85
# 2. Click the block element at block_index
# Example: if block_index=5, click the 6th block element (0-indexed)
browser_click on the element at position block_index in the editor
# 3. Paste image
browser_press_key: Meta+v
# 4. Wait for upload (use short time, returns immediately when done)
browser_wait_for textGone="正在上传媒体" time=2
注意: 每插入一张图片后,后续图片的实际位置会偏移。建议按 block_index 从大到小的顺序插入图片。
如果有3张图片,block_index 分别为 5, 12, 27:
重要: Markdown 中的 --- 分割线不能通过 HTML <hr> 标签粘贴(X Articles 会忽略它)。必须通过 X Articles 的 Insert 菜单插入。
X Articles 有自己的原生分割线元素,只能通过 Insert > Divider 菜单插入。HTML <hr> 标签会被完全忽略。
For each divider (from dividers array), in reverse order of block_index:
# 1. Click the block element at block_index position
browser_click on the element at position block_index in the editor
# 2. Open Insert menu
browser_click on "Insert" button (Add Media button)
# 3. Click Divider menu item
browser_click on "Divider" menuitem
# Divider is inserted at cursor position
和图片一样,按 block_index 从大到小的顺序插入分割线,避免位置偏移问题。
建议先插入所有图片,再插入所有分割线。两者都按 block_index 从大到小的顺序:
--- must be inserted via Insert > Divider menu (HTML <hr> is ignored)| Element | Support | Notes |
|---|---|---|
H2 (##) | Native | Section headers |
Bold (**) | Native | Strong emphasis |
Italic (*) | Native | Emphasis |
Links ([](url)) | Native | Hyperlinks |
| Ordered lists | Native | 1. 2. 3. |
| Unordered lists | Native | - bullets |
Blockquotes (>) | Native | Quoted text |
| Code blocks | Converted | → Blockquotes |
| Tables | Converted | → PNG images |
| Mermaid | Converted | → PNG images |
| H3+ headers | Converted | → H2 or bold |
Dividers (---) | Menu insert | → Insert > Divider |
User: "Publish /path/to/article.md to X"
# Step 0: Analyze content
# Found: 1 table, 1 mermaid diagram, 2 H3 headers
# Step 0.1: Convert table to image
node ~/.claude/skills/diagram-to-image/scripts/diagram-to-image.mjs /tmp/table-1.md -o /tmp/table-1.png
# Step 0.2: Convert mermaid to image
node ~/.claude/skills/diagram-to-image/scripts/diagram-to-image.mjs /tmp/mermaid-1.mmd -o /tmp/mermaid-1.png
# Step 0.3: Create modified markdown with image refs and flattened headers
# Save to /tmp/article_modified.md
# Step 1: Parse modified markdown
python ~/.claude/skills/publish-x-article/scripts/parse_markdown.py /tmp/article_modified.md > /tmp/article.json
python ~/.claude/skills/publish-x-article/scripts/parse_markdown.py /tmp/article_modified.md --html-only > /tmp/article_html.html
title)python ~/.claude/skills/publish-x-article/scripts/copy_to_clipboard.py html --file /tmp/article_html.html
Then: browser_press_key Meta+vpython copy_to_clipboard.py image /path/to/img.jpg --quality 85
block_index positionafter_text 仍保留用于人工核验关键理解: browser_wait_for 的 textGone 参数会在文字消失时立即返回,time 只是最大等待时间,不是固定等待时间。
# 正确用法:短 time 值,条件满足立即返回
browser_wait_for textGone="正在上传媒体" time=2
# 错误用法:固定长时间等待
browser_wait_for time=5 # 无条件等待5秒,浪费时间
pip install pillow--type mermaid### → ## or **bold**--quality 70browser_wait_for time=2