关于 obsidian-to-x
面向 Obsidian 用户的 X 发布技能,可通过真实 Chrome 浏览器发布普通帖子、视频、引用帖子和长文文章。它能识别当前笔记并将 Obsidian Markdown 转换为相应的 X 内容格式。
主要功能
- 01发布文本、图片、视频和长文
- 02读取当前活动 Obsidian 文件
- 03转换 Obsidian Markdown 与图片语法
- 04根据 frontmatter 选择文章或普通帖子
- 05浏览器中预览并手动确认发布
适用场景
- 01将当前 Obsidian 笔记发布为 X 文章
- 02把 Markdown 笔记转为含图片的普通帖子
- 03发布视频帖子或带评论的引用帖子
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ libukai/ awesome-agent-skills --skill obsidian-to-x安装后在 Claude Code 中输入/obsidian-to-x确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/articles.mdbrowser-automation-lessons.mdobsidian-conversion.mdobsidian-integration.mdregular-posts.mdtroubleshooting.mdscripts/bun.lockcheck-editor-content.tscheck-paste-permissions.tscopy-to-clipboard.tsinsert-code-blocks.tsmd-to-article.tsmd-to-post.tsobsidian-resolver.tspackage.jsonpaste-from-clipboard.tspublish-active.shtest-annotation-debug.tstest-code-insertion.tsx-article.tsx-post.tsx-quote.tsx-utils.tsx-video.ts详细介绍
发布到 X(Twitter)
通过真实的 Chrome 浏览器向 X 发布文本、图片、视频和长文(可绕过反机器人检测)。
默认行为(无额外指示)
当用户在未指定发布内容的情况下调用此技能时(例如只说“发到 X”或使用斜杠命令):
-
先清理 Chrome CDP 进程(参见下文的 CDP 清理)
-
获取当前活动文件,按优先级依次尝试:
优先级 1:
<current_note>标签(由 Claudian 注入,最准确) 检查用户消息末尾是否有<current_note>标签,直接提取路径,无需执行任何命令。优先级 2:workspace.json(本地备用方案)
jq -r '.lastOpenFiles[] | select(endswith(".md"))' .obsidian/workspace.json | head -1优先级 3:Obsidian CLI(最后手段)
obsidian file active -
使用 Read 工具读取文件内容
-
自动检测发布类型:
- 检查文件的 frontmatter 中是否有
是否长文: true 是否长文: true→ 作为 X Article(长文)发布是否长文: false、未设置是否长文,或没有 frontmatter → 作为 普通帖子(短文)发布
- 检查文件的 frontmatter 中是否有
-
告知用户检测到的类型并继续发布
-
执行相应的工作流:
- 对于 X Article:使用
x-article.ts发布(内部会处理 Obsidian 转换) - 对于普通帖子:使用
md-to-post.ts转换 → 使用x-post.ts发布
- 对于 X Article:使用
-
通过 Bash 后台进程执行发布脚本(必需——不要使用 Agent 的
run_in_background=true):- 始终使用 Bash
&并将日志重定向到 vault:bun ... > .temp/x-article-output.log 2>&1 & - 切勿使用带
run_in_background=true的 Agent 工具——输出文件会写入/private/tmp/,该路径会被 vault 权限钩子拦截,导致 TaskOutput 失败并触发重复执行 - 通过读取
.temp/x-article-output.log轮询进度:sleep N && cat .temp/x-article-output.log | tail -30
- 始终使用 Bash
-
成功检测:检查
.temp/x-article-output.log中的成功标记:- 最佳方法:统计
Image upload verified的出现次数,并与预期图片数量匹配 - 替代方法:查找
Post composed (preview mode)或Browser remains open - 对于 X Article:查找
Article composed或Browser remains open - 使用
sleep 15 && cat .temp/x-article-output.log | tail -30轮询 - 检测到标记后立即报告成功,不要等待任务完成
- 最佳方法:统计
示例:
User: "发到 X"
AI: ✓ Detected current file: Articles/news/my-article.md
✓ Found `是否文章: true` → Publishing as X Article
[proceeds with article publishing workflow]
CDP 清理
在每个发布脚本运行前执行此操作,以防止出现“Chrome 调试端口未就绪”错误。自动执行——无需询问用户。
pkill -f "Chrome.*remote-debugging-port"; pkill -f "Chromium.*remote-debugging-port"; sleep 2
内容类型
X Articles 与普通帖子:
| 功能 | X Articles | 普通帖子 |
|---|---|---|
| 内容 | 富文本(Markdown) | 仅纯文本 |
| 格式 | ✅ 粗体、斜体、标题、列表 | ❌ 全部移除 |
| 代码块 | ✅ 语法高亮 | ❌ 不支持 |
| 图片 | ✅ 多张图片 | ✅ 最多 4 张图片 |
| 长度 | 长文(不限) | 短文(280 个字符) |
| 要求 | X Premium | 免费 |
| 脚本 | x-article.ts | x-post.ts |
| 转换 | md-to-article.ts | md-to-post.ts |
使用场景:
- X Articles:博客文章、教程、包含代码的技术文章
- 普通帖子:快速更新、公告、简单的文本和图片
快速开始
适用于想要发布当前活动文章的 Obsidian 用户:
bash ${SKILL_DIR}/scripts/publish-active.sh
此操作会自动:
- 检测活动文件(通过 workspace.json 或 Obsidian CLI)
- 将 Obsidian 语法转换为 X 格式
- 打开已填入内容的 X Articles 编辑器
脚本目录
重要:所有脚本都位于此技能的 scripts/ 子目录中。
Agent 执行说明:
- 将此 SKILL.md 文件所在目录路径确定为
SKILL_DIR - 脚本路径 =
${SKILL_DIR}/scripts/<script-name>.ts - 将本文档中的所有
${SKILL_DIR}替换为实际路径 - 解析
${BUN_X}运行时:如果已安装bun→bun;如果有npx→npx -y bun;否则建议安装 bun
脚本参考:
| 脚本 | 用途 |
|---|---|
| 发布脚本 | |
scripts/x-post.ts | 发布常规帖子(文本 + 图片,最多 4 张) |
scripts/x-video.ts | 发布视频帖子(文本 + 视频) |
scripts/x-quote.ts | 发布带评论的引用推文 |
scripts/x-article.ts | 发布 X Articles(富文本 + 图片 + 代码) |
| 转换脚本 | |
scripts/md-to-post.ts | 将 Obsidian Markdown 转换为纯文本 + 图片(用于帖子) |
scripts/md-to-article.ts | 将 Obsidian Markdown 转换为 HTML + 图片(用于 Articles) |
| 实用工具 | |
scripts/publish-active.sh | 一键发布当前 Obsidian 文件 |
前置条件
- Google Chrome 或 Chromium
bun运行时- 首次运行:手动登录 X(会保存会话)
- Obsidian 集成:
jq工具(macOS 上运行brew install jq)
发布前检查(可选)
首次使用前,建议运行环境检查:
${BUN_X} ${SKILL_DIR}/scripts/check-paste-permissions.ts
检查项:Chrome、Bun、辅助功能权限、剪贴板、粘贴快捷键。
如果任何检查未通过,请针对对应项目提供修复指导:
| 检查项 | 修复方法 |
|---|---|
| Chrome | 安装 Chrome 或设置 X_BROWSER_CHROME_PATH 环境变量 |
| Bun 运行时 | brew install oven-sh/bun/bun(macOS)或 npm install -g bun |
| 辅助功能(macOS) | 系统设置 → 隐私与安全性 → 辅助功能 → 启用终端应用 |
| 粘贴快捷键(Linux) | 安装 xdotool(X11)或 ydotool(Wayland) |
Obsidian 集成
对于 Obsidian 用户,此技能可以自动检测当前活动文件并转换 Obsidian 专用语法。
快速工作流:
# One-command publish
bash ${SKILL_DIR}/scripts/publish-active.sh
手动工作流:
# Step 1: Get active file (workspace.json method, 39x faster)
ACTIVE_FILE=$(jq -r '.lastOpenFiles[0]' .obsidian/workspace.json)
# Step 2: Publish (x-article.ts handles Obsidian conversion internally)
bun ${SKILL_DIR}/scripts/x-article.ts "$ACTIVE_FILE"
有关 Obsidian 集成的详细信息,请参阅 references/obsidian-integration.md:
- 如何检测活动文件(workspace.json 与 CLI)
- 性能比较(0.007s 与 0.274s)
- 错误处理和回退策略
有关 Obsidian 语法转换,请参阅 references/obsidian-conversion.md:
- 转换
![[]]图片语法 - 处理中文 frontmatter 字段
- 手动转换命令
常规帖子
文本 + 最多 4 张图片。仅纯文本(会移除所有 Markdown 格式)。
从 Obsidian Markdown 创建
步骤 1:清理 CDP(参阅 CDP 清理 部分)
步骤 2:将 Markdown 转换为纯文本 + 图片
# Extract content from Markdown file
# Supports both standard Markdown  and Obsidian ![[path]] image syntax
# --output-dir keeps downloaded images inside the vault (.temp) to avoid permission issues
bun ${SKILL_DIR}/scripts/md-to-post.ts "Articles/my-post.md" --output-dir ".temp/x-post" > .temp/post-content.json
TEXT=$(jq -r '.text' .temp/post-content.json)
IMAGES=$(jq -r '.images[]' .temp/post-content.json)
支持的图片语法:
- ✅ 标准 Markdown:
 - ✅ Obsidian 语法:
![[path/to/image.png]] - ✅ 网络 URL:
或![[https://example.com/image.jpg]] - 本地路径会转换为绝对路径
- 网络图片会自动并行下载(比顺序下载快 3–4 倍)
步骤 2.5:提取封面图作为第一张图片
从文件 frontmatter 中读取 封面 属性;若存在,则将其路径作为第一张图片:
# 提取 封面 属性(支持 ![[path]] 和裸路径两种格式)
COVER_RAW=$(grep -m1 '^封面:' "Articles/my-post.md" | sed 's/^封面: *//' | tr -d '"')
# 解析 Obsidian wikilink 格式 ![[path]] → path
COVER_PATH=$(echo "$COVER_RAW" | sed 's/^!\[\[//;s/\]\]$//')
# 组合图片列表:封面优先,正文图片补充(总数上限 4 张)
IMAGE_ARGS=""
if [ -n "$COVER_PATH" ]; then
IMAGE_ARGS="--image \"$COVER_PATH\""
fi
for img in $IMAGES; do
IMAGE_ARGS="$IMAGE_ARGS --image \"$img\""
done
- 若
封面属性为空或不存在,则跳过,仅使用正文图片 - 图片总数上限为 4 张(受 x-post.ts 限制),超出部分会自动截断
步骤 3:发布帖子
eval "${BUN_X} ${SKILL_DIR}/scripts/x-post.ts \"$TEXT\" $IMAGE_ARGS"
直接使用
${BUN_X} ${SKILL_DIR}/scripts/x-post.ts "Hello!" --image ./photo.png
参数:
| 参数 | 描述 |
|---|---|
<text> | 帖子内容(纯文本,位置参数) |
--image <path> | 图片文件(可重复,最多 4 个) |
--profile <dir> | 自定义 Chrome 配置文件 |
内容处理:
- ✅ 纯文本(剥除所有格式)
- ✅ 图片(最多 4 张)
- ❌ 不支持富文本格式
- ❌ 不支持代码块
- ❌ 不支持 HTML
浏览器行为:
- 脚本会打开浏览器并填入内容
- 浏览器会保持打开,供手动检查
- 用户可以按自己的节奏检查、编辑和发布
- 完成后由用户手动关闭浏览器
- 添加
--submit标志可自动发布(2 秒后关闭)
AI 成功检测(用于后台执行):
- 不要等待任务完成(浏览器会无限期保持打开)
- 最佳方法:统计输出中
Image upload verified的次数,并与预期图片数量匹配 - 替代方法:检查是否出现
Post composed (preview mode)或Browser remains open - 设置较短的超时时间(10-15 秒),然后检查输出内容
- 检测到标记后立即报告成功
- 示例工作流:
1. Know you're uploading 3 images 2. Wait 10-15s for uploads 3. Check output: grep "Image upload verified" | wc -l 4. If count == 3 → Report success immediately
视频帖子
文本 + 视频文件。
步骤 1:清理 CDP(参见 CDP 清理 部分)
步骤 2:发布视频帖子
${BUN_X} ${SKILL_DIR}/scripts/x-video.ts "Check this out!" --video ./clip.mp4
参数:
| 参数 | 描述 |
|---|---|
<text> | 帖子内容(位置参数) |
--video <path> | 视频文件(MP4、MOV、WebM) |
--profile <dir> | 自定义 Chrome 配置文件 |
限制:普通用户最长 140 秒,Premium 用户最长 60 分钟。处理时间:30-60 秒。
引用推文
引用现有推文并添加评论。
步骤 1:清理 CDP(参见 CDP 清理 部分)
步骤 2:发布引用推文
${BUN_X} ${SKILL_DIR}/scripts/x-quote.ts https://x.com/user/status/123 "Great insight!"
参数:
| 参数 | 描述 |
|---|---|
<tweet-url> | 要引用的 URL(位置参数) |
<comment> | 评论文本(位置参数,可选) |
--profile <dir> | 自定义 Chrome 配置文件 |
X 文章
长篇 Markdown 文章(需要 X Premium)。
步骤 1:清理 CDP(参见 CDP 清理 部分)
步骤 2:发布文章
${BUN_X} ${SKILL_DIR}/scripts/x-article.ts article.md
${BUN_X} ${SKILL_DIR}/scripts/x-article.ts article.md --cover ./cover.jpg
参数:
| 参数 | 描述 |
|---|---|
<markdown> | Markdown 文件(位置参数) |
--cover <path> | 封面图片 |
--title <text> | 覆盖标题 |
Frontmatter:支持 YAML front matter 中的 title / 标题、cover_image / 封面 / 配图。
标题解析(适用于 X 文章):
# 优先读 frontmatter 的 `标题` 属性,为空则 fallback 到文件名
TITLE=$(obsidian property:read name="标题" path="$NOTE_PATH" 2>/dev/null | tr -d '[:space:]')
if [ -z "$TITLE" ]; then
TITLE=$(basename "$NOTE_PATH" .md)
fi
# 传入脚本
${BUN_X} ${SKILL_DIR}/scripts/x-article.ts "$NOTE_PATH" --title "$TITLE"
注意:脚本会打开浏览器并填入文章内容。用户需要检查并手动发布。
代码块支持
代码块会自动从 Markdown 中提取并插入 X 文章编辑器。支持所有语言(JavaScript、Python、TypeScript、Rust、Go、Shell 等)。无需手动操作。
故障排查
常见问题:
- Chrome 调试端口尚未就绪 → 始终先清理 CDP 进程(见上文)
- macOS 辅助功能权限错误 → 在系统设置中启用
- 代码块未插入 → 此过程为自动执行,请检查控制台是否有错误
- 图片临时路径位于 vault 之外 →
md-to-post.ts默认会将图片下载到系统/tmp,vault 限制的钩子可能会阻止此操作。解决方法:始终传入--output-dir ".temp/x-post",将图片保留在 vault 内:bun ${SKILL_DIR}/scripts/md-to-post.ts "Articles/my-post.md" --output-dir ".temp/x-post"
详细故障排查信息,请参见 references/troubleshooting.md。
参考资料
references/obsidian-integration.md- Obsidian 文件检测与集成references/obsidian-conversion.md- 将 Obsidian 语法转换为标准 Markdownreferences/regular-posts.md- 常规帖子工作流与故障排查references/articles.md- X 文章详细指南references/troubleshooting.md- 常见问题与解决方案references/browser-automation-lessons.md- 浏览器自动化模式与经验总结(CDP、DraftJS、后台标签页)
扩展支持
通过 EXTEND.md 使用自定义配置。请检查以下路径(按优先级排序):
.libukai-skills/obsidian-to-x/EXTEND.md(项目目录)$HOME/.libukai-skills/obsidian-to-x/EXTEND.md(用户主目录)
EXTEND.md 支持:默认 Chrome 配置文件
备注
- 首次运行:需要手动登录(会保留会话)
- 所有脚本都会在浏览器中填写内容,并保持浏览器打开以供手动检查
- 浏览器会一直保持打开状态,直到用户手动关闭(使用
--submit标志时除外) - 跨平台:macOS、Linux、Windows