重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
publish-x-article by sugarforever/01coder-agent-skills
npx skills add https://github.com/sugarforever/01coder-agent-skills --skill publish-x-article将 Markdown 内容发布到 X (Twitter) 文章编辑器,通过富文本转换保留格式。通过将不支持的元素转换为图片,自动处理 X Premium 的限制。
此技能灵感来源于并基于 wshuyi/x-article-publisher-skill。感谢原作者的基础工作。
重要提示:在处理文章之前,如果尚未了解,请询问用户的 X 订阅类型。
在发布之前,我需要了解您的 X 订阅类型以正确处理格式:
1. **X Premium** - 基础版 ($8/月)
2. **X Premium+** - 高级版 ($16/月)
您使用的是哪个版本?(Premium / Premium+)
一旦用户回答,请记住他们的订阅类型,以便在本次会话的剩余部分使用。除非用户明确想要更改,否则不要再次询问。
| 功能 | X Premium | X Premium+ |
|---|---|---|
H1 标题 (#) | 仅用作标题 | 仅用作标题 |
H2 标题 (##) |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 支持 |
| 支持 |
H3+ 标题 (### 等) | 不支持 | 支持 |
| Markdown 表格 | 不支持 | 支持 |
| Mermaid 图表 | 不支持 | 不支持 (X 不支持) |
| 代码块 | 引用块 | 引用块 |
| 粗体、斜体、链接 | 支持 | 支持 |
| 列表 | 支持 | 支持 |
| 引用块 | 支持 | 支持 |
| 图片 | 支持 | 支持 |
X Premium (基础版):
X Premium+ (高级版):
pip install Pillow pyobjc-framework-Cocoa markdownpip install Pillow pywin32 clip-util markdown位于 ~/.claude/skills/publish-x-article/scripts/:
解析 Markdown 并提取结构化数据:
python parse_markdown.py <markdown_file> [--output json|html] [--html-only]
返回 JSON,包含:title, cover_image, content_images (带有用于定位的 block_index), html, total_blocks
将图片或 HTML 复制到系统剪贴板:
# 复制图片 (可选压缩)
python copy_to_clipboard.py image /path/to/image.jpg [--quality 80]
# 复制 HTML 用于富文本粘贴
python copy_to_clipboard.py html --file /path/to/content.html
通过 diagramless.xyz API 将 Mermaid 图表和 Markdown 表格转换为 PNG 图片:
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
在 发布之前,扫描 Markdown 中不支持的元素并将其转换为图片。
# 检查 markdown 文件中的不支持元素
cat /path/to/article.md
查找:
###, #### 等| 字符形成表格结构的行 ```mermaid检测到表格时:
# 1. 提取表格到临时文件
cat > /tmp/table.md << 'TABLE_EOF'
| Column 1 | Column 2 | Column 3 |
|----------|----------|----------|
| Data 1 | Data 2 | Data 3 |
TABLE_EOF
# 2. 通过 diagramless.xyz API 转换为图片
node ~/.claude/skills/diagram-to-image/scripts/diagram-to-image.mjs /tmp/table.md -o /tmp/table-001.png
# 3. 在 markdown 中将表格替换为图片引用
# 
检测到 mermaid 块时:
# 1. 提取 mermaid 到临时文件
cat > /tmp/diagram.mmd << 'MERMAID_EOF'
flowchart TD
A[Start] --> B[Process]
B --> C[End]
MERMAID_EOF
# 2. 通过 diagramless.xyz API 转换为图片
node ~/.claude/skills/diagram-to-image/scripts/diagram-to-image.mjs /tmp/diagram.mmd -o /tmp/diagram-001.png
# 3. 在 markdown 中将 mermaid 块替换为图片引用
# 
目标: 在 X Premium 仅支持 H2 的限制内,保留文章的逻辑结构和可读性。
AI 指南:
当你在 Premium 用户的文章中遇到 H3、H4 或更深层的标题时,思考作者的意图:
如果标题在某个章节下引入了一个不同的子主题,将其转换为 粗体文本 作为段落开头。这样可以在不破坏 X 格式的情况下保持视觉层次结构。
如果标题是一个主要章节,但恰好是 H3,考虑将其提升为 H2 —— 但前提是这不会创建一个扁平、无意义的结构。文章仍应保持逻辑流畅。
如果存在深层层次结构 (H2 → H3 → H4),请仔细扁平化:
保留意义重于结构。 像 ### 为什么这很重要 这样的标题可能会变成一个粗体的开头:**为什么这很重要?** 后面跟着内容。请运用你的判断。
阅读内容。 如果一个 H3 标题只是“示例”或“注意”,它可能更适合作为引用块或内联强调,而不是独立的粗体行。
目标不是机械转换 —— 而是创建一个在 X 上阅读体验良好,同时尊重作者意图的文章。
在发布之前,通读文章并为其在 X 上发布做准备:
理解文章结构 —— 先阅读一遍。主要章节是什么?作者如何使用标题来组织思路?
处理表格和 mermaid 图表 —— 这些需要转换为图片。提取每一个,转换为 PNG,并记录它们应该插入的位置。
根据订阅层级调整标题:
创建修改后的 markdown —— 将你调整后的版本保存到临时文件,准备进行解析。
目标是在 X 上阅读自然的文章,而不是机械转换的文档。
策略: "先文后图后分割线" (Text First, Images Second, Dividers Last)
对于包含图片和分割线的文章,首先粘贴所有文本内容,然后使用块索引在正确位置插入图片和分割线。
目标 : 最小化操作之间的等待时间,实现流畅的自动化体验。
大多数浏览器操作 (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)
→ ...
在开始浏览器操作之前,先完成所有准备工作:
这样浏览器操作阶段可以连续执行,不需要中途停下来处理数据。
首先,阅读文章。 理解文章内容、结构以及作者想要传达的信息。
重要提示: 切勿修改用户的原始文件。如果需要调整:
将调整后的版本另存为副本 (例如,/tmp/article_adapted.md 或与原始文件同位置的 article_for_x.md)
告诉用户更改了什么以及两个文件的位置:
我已将您的文章调整为适合 X Premium 的版本。以下是更改内容:
- 将 2 个表格转换为图片
- 将 3 个 H3 标题重构为粗体文本以改善流畅性
原始文件保留在:/path/to/article.md
调整后的版本在:/path/to/article_for_x.md
使用调整后的副本进行发布
这确保用户可以查看更改,并保持其原始作品完好无损。
自问:
创建一个修改后的 markdown 版本,使其在 Premium 的限制内正常工作,同时保持可读性。
自问:
# 表格 → PNG (自动检测为表格)
node ~/.claude/skills/diagram-to-image/scripts/diagram-to-image.mjs /tmp/table-1.md -o /tmp/table-1.png
# Mermaid → PNG (自动检测为 mermaid)
node ~/.claude/skills/diagram-to-image/scripts/diagram-to-image.mjs /tmp/diagram-1.mmd -o /tmp/diagram-1.png
在 markdown 中用图片引用替换这些元素,将它们放置在原始元素所在的位置。
使用 parse_markdown.py 提取所有结构化数据:
python ~/.claude/skills/publish-x-article/scripts/parse_markdown.py /path/to/modified_article.md
输出 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
}
关键字段:
block_index: 图片/分割线应插入在此索引处的块元素之后 (0-indexed)total_blocks: HTML 中块元素的总数after_text: 仅用于参考/调试,不用于定位dividers: 分割线位置数组 (markdown --- 必须通过 X 的菜单插入,而非 HTML <hr>)将 HTML 保存到临时文件以供剪贴板使用:
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 后才出现,会导致超时。
如果需要登录,提示用户手动登录。
使用 Python 将 HTML 复制到系统剪贴板,然后粘贴:
# 复制 HTML 到剪贴板
python ~/.claude/skills/publish-x-article/scripts/copy_to_clipboard.py html --file /tmp/article_html.html
然后在浏览器中:
browser_click on editor textbox
browser_press_key: Meta+v
这样可以保留所有富文本格式 (H2, 粗体, 链接, 列表)。
关键改进 : 使用 block_index 精确定位,而非依赖文字匹配。
粘贴 HTML 后,编辑器中的内容结构为一系列块元素 (段落、标题、引用等)。每张图片的 block_index 表示它应该插入在第 N 个块元素之后。
block_index 点击对应的块元素对于每个内容图片 (来自 content_images 数组):
# 1. 复制图片到剪贴板 (带压缩)
python ~/.claude/skills/publish-x-article/scripts/copy_to_clipboard.py image /path/to/img.jpg --quality 85
# 2. 点击 block_index 处的块元素
# 示例:如果 block_index=5,点击第 6 个块元素 (0-indexed)
browser_click on the element at position block_index in the editor
# 3. 粘贴图片
browser_press_key: Meta+v
# 4. 等待上传完成 (使用短时间,完成后立即返回)
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> 标签会被完全忽略。
对于每个分割线 (来自 dividers 数组),按 block_index 从大到小 的顺序:
# 1. 点击 block_index 位置的块元素
browser_click on the element at position block_index in the editor
# 2. 打开 Insert 菜单
browser_click on "Insert" button (Add Media button)
# 3. 点击 Divider 菜单项
browser_click on "Divider" menuitem
# 分割线插入在光标位置
和图片一样,按 block_index 从大到小 的顺序插入分割线,避免位置偏移问题。
建议先插入所有图片,再插入所有分割线。两者都按 block_index 从大到小的顺序:
--- 必须通过 Insert > Divider 菜单插入 (HTML <hr> 会被忽略)| 元素 | 支持情况 | 备注 |
|---|---|---|
H2 (##) | 原生支持 | 章节标题 |
粗体 (**) | 原生支持 | 强调 |
斜体 (*) | 原生支持 | 强调 |
链接 ([](url)) | 原生支持 | 超链接 |
| 有序列表 | 原生支持 | 1. 2. 3. |
| 无序列表 | 原生支持 | - 项目符号 |
引用块 (>) | 原生支持 | 引用文本 |
| 代码块 | 已转换 | → 引用块 |
| 表格 | 已转换 | → PNG 图片 |
| Mermaid | 已转换 | → PNG 图片 |
| H3+ 标题 | 已转换 | → H2 或粗体 |
分割线 (---) | 菜单插入 | → Insert > Divider |
用户:"将 /path/to/article.md 发布到 X"
# 步骤 0: 分析内容
# 发现:1 个表格,1 个 mermaid 图表,2 个 H3 标题
# 步骤 0.1: 将表格转换为图片
node ~/.claude/skills/diagram-to-image/scripts/diagram-to-image.mjs /tmp/table-1.md -o /tmp/table-1.png
# 步骤 0.2: 将 mermaid 转换为图片
node ~/.claude/skills/diagram-to-image/scripts/diagram-to-image.mjs /tmp/mermaid-1.mmd -o /tmp/mermaid-1.png
# 步骤 0.3: 创建包含图片引用和扁平化标题的修改后 markdown
# 保存到 /tmp/article_modified.md
# 步骤 1: 解析修改后的 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
2. 导航到 https://x.com/compose/articles
3. 点击 create,上传封面图片 (仅封面使用 browser_file_upload)
4. 填写标题 (来自 JSON: title)
5. 复制并粘贴 HTML:
python ~/.claude/skills/publish-x-article/scripts/copy_to_clipboard.py html --file /tmp/article_html.html
然后:browser_press_key Meta+v 6. 对于每个内容图片 (包括转换后的表格/mermaid PNG),按 block_index 从大到小的顺序:
python copy_to_clipboard.py image /path/to/img.jpg --quality 85
* 点击 `block_index` 位置的块元素
* browser_press_key Meta+v
* 等待直到上传完成
7. 在预览中验证 8. "草稿已保存。请手动审阅并发布。"
after_text 仍保留用于人工核验关键理解 : browser_wait_for 的 textGone 参数会在文字消失时立即返回 ,time 只是最大等待时间,不是固定等待时间。
# 正确用法:短 time 值,条件满足立即返回
browser_wait_for textGone="正在上传媒体" time=2
# 错误用法:固定长时间等待
browser_wait_for time=5 # 无条件等待5秒,浪费时间
pip install pillow--type mermaid### → ## 或 **粗体**--quality 70 压缩图片browser_wait_for time=2每周安装次数
60
仓库
GitHub 星标数
78
首次出现
2026年1月28日
安全审计
安装于
cursor53
gemini-cli52
codex52
opencode52
github-copilot49
amp49
Skills CLI 使用指南:AI Agent 技能包管理器安装与管理教程
50,200 周安装
UI/UX Pro Max 设计指南:避免AI生成感,打造高级SaaS/着陆页设计原则与实现
4,000 周安装
Apify Actor 开发指南:创建无服务器自动化程序与网络爬虫
4,000 周安装
数据可视化指南:图表选择、Python代码与设计原则
4,000 周安装
Three.js 动画教程 - 从程序化动画到关键帧系统完整指南
3,900 周安装
LangChain create_agent 智能体创建教程 - 构建AI助手与工具集成
4,100 周安装
Claude-to-IM 桥接技能:一键连接 Claude AI 到 Telegram、飞书、微信等主流通讯平台
4,000 周安装