agentsclimarketplace

Obsidian to x

Skill ComeOnOliver/skillshub/skills/libukai/awesome-agent-skills/obsidian-to-x

🧠 The right skill, one API call. AI agent skills registry with token-efficient skill resolution. 5,000+ skills from 500+ top repos.

Install
npx -y skills add ComeOnOliver/skillshub --skill obsidian-to-x

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

SKILL.md

13.2 KB, as published. Nobody here has run it

Post to X (Twitter)

Posts text, images, videos, and long-form articles to X via real Chrome browser (bypasses anti-bot detection).

Default Behavior (No Additional Instructions)

When user invokes this skill without specifying what to publish (e.g., just says "ε‘εˆ° X" or uses slash command):

  1. Clean Chrome CDP processes first (REQUIRED - prevents port conflicts):

    pkill -f "Chrome.*remote-debugging-port" 2>/dev/null; pkill -f "Chromium.*remote-debugging-port" 2>/dev/null; sleep 2
    
  2. Get current active file from Obsidian workspace:

    jq -r '.lastOpenFiles[0]' .obsidian/workspace.json
    
  3. Read the file content using Read tool

  4. Auto-detect publishing type:

    • Check if file has frontmatter with title:, ζ ‡ι’˜:, or Title: field
    • Has title in frontmatter β†’ Publish as X Article (long-form)
    • No frontmatter or no title β†’ Publish as Regular Post (short-form)
  5. Inform user of detected type and proceed with publishing

  6. Execute appropriate workflow:

    • For X Article: Convert with obsidian-to-article.ts β†’ Publish with x-article.ts
    • For Regular Post: Convert with obsidian-to-post.ts β†’ Publish with x-post.ts
  7. Success Detection: When running publishing scripts in background, check output for success markers:

    • Best method: Count Image upload verified occurrences matching expected image count
    • Alternative: Look for Post composed (preview mode) or Browser remains open
    • For X Articles: Look for Article composed or Browser remains open
    • Use short timeout (10-15s) with block=false, then check output content
    • Report success immediately when markers detected, don't wait for task completion
    • Example: 3 images β†’ wait for 3x Image upload verified + text typing completion

Example:

User: "ε‘εˆ° X"
AI: βœ“ Detected current file: Articles/news/my-article.md
    βœ“ Found frontmatter with title β†’ Publishing as X Article
    [proceeds with article publishing workflow]

Content Types

X Articles vs Regular Posts:

FeatureX ArticlesRegular Posts
ContentRich text (Markdown)Plain text only
Formattingβœ… Bold, italic, headers, lists❌ All stripped
Code blocksβœ… Syntax highlighting❌ Not supported
Imagesβœ… Multiple imagesβœ… Max 4 images
LengthLong-form (unlimited)Short (280 chars)
RequirementsX PremiumFree
Scriptx-article.tsx-post.ts
Conversionobsidian-to-x.tsextract-post-content.ts

When to use:

  • X Articles: Blog posts, tutorials, technical articles with code
  • Regular Posts: Quick updates, announcements, simple text + images

AI Auto-Detection (for Obsidian files):

When user requests to publish the currently active Obsidian file without specifying the type:

  1. Read the file content using Read tool
  2. Check for frontmatter (YAML block between --- markers at the start)
  3. Auto-select publishing type:
    • Has frontmatter with title field (title:, ζ ‡ι’˜:, or Title:) β†’ Publish as X Article
    • No frontmatter or no title field β†’ Publish as Regular Post
  4. Inform the user of the detected type before publishing

IMPORTANT:

  • ONLY use frontmatter presence to determine publishing type
  • DO NOT consider content length, word count, or any other factors
  • Even if content is very long (800+ words), if there's no frontmatter with title β†’ publish as Regular Post
  • Even if content is very short, if there's frontmatter with title β†’ publish as X Article
  • Strictly follow the frontmatter rule without exceptions

Example decision logic:

File with frontmatter:
---
title: My Technical Article
---
Content here...
β†’ Detected: X Article (has title in frontmatter)

File without frontmatter:
Just some quick thoughts to share...
β†’ Detected: Regular Post (no frontmatter)

Quick Start

For Obsidian users who want to publish the currently active article:

bash ${SKILL_DIR}/scripts/publish-active.sh

This automatically:

  1. Detects the active file (via workspace.json or Obsidian CLI)
  2. Converts Obsidian syntax to X format
  3. Opens X Articles editor with content filled in

Script Directory

Important: All scripts are located in the scripts/ subdirectory of this skill.

Agent Execution Instructions:

  1. Determine this SKILL.md file's directory path as SKILL_DIR
  2. Script path = ${SKILL_DIR}/scripts/<script-name>.ts
  3. Replace all ${SKILL_DIR} in this document with the actual path
  4. Resolve ${BUN_X} runtime: if bun installed β†’ bun; if npx available β†’ npx -y bun; else suggest installing bun

Script Reference:

ScriptPurpose
Publishing Scripts
scripts/x-post.tsPublish regular posts (text + images, max 4)
scripts/x-video.tsPublish video posts (text + video)
scripts/x-quote.tsPublish quote tweet with comment
scripts/x-article.tsPublish X Articles (rich text + images + code)
Conversion Scripts
scripts/obsidian-to-post.tsConvert Obsidian Markdown β†’ plain text + images (for Posts)
scripts/obsidian-to-article.tsConvert Obsidian Markdown β†’ X Articles format (for Articles)
Utilities
scripts/publish-active.shOne-command publish for active Obsidian file

Prerequisites

  • Google Chrome or Chromium
  • bun runtime
  • First run: log in to X manually (session saved)
  • For Obsidian integration: jq tool (brew install jq on macOS)

Pre-flight Check (Optional)

Before first use, suggest running the environment check:

${BUN_X} ${SKILL_DIR}/scripts/check-paste-permissions.ts

Checks: Chrome, Bun, Accessibility permissions, clipboard, paste keystroke.

If any check fails, provide fix guidance per item:

CheckFix
ChromeInstall Chrome or set X_BROWSER_CHROME_PATH env var
Bun runtimebrew install oven-sh/bun/bun (macOS) or npm install -g bun
Accessibility (macOS)System Settings β†’ Privacy & Security β†’ Accessibility β†’ enable terminal app
Paste keystroke (Linux)Install xdotool (X11) or ydotool (Wayland)

Obsidian Integration

For Obsidian users, this skill can automatically detect the currently active file and convert Obsidian-specific syntax.

Quick workflow:

# One-command publish
bash ${SKILL_DIR}/scripts/publish-active.sh

Manual workflow:

# Step 1: Get active file (workspace.json method, 39x faster)
ACTIVE_FILE=$(jq -r '.lastOpenFiles[0]' .obsidian/workspace.json)

# Step 2: Convert Obsidian syntax
bun ${SKILL_DIR}/scripts/obsidian-to-article.ts "$ACTIVE_FILE" "Temp/converted.md"

# Step 3: Publish
bun ${SKILL_DIR}/scripts/x-article.ts "Temp/converted.md"

For detailed Obsidian integration, see references/obsidian-integration.md:

  • How to detect active file (workspace.json vs CLI)
  • Performance comparison (0.007s vs 0.274s)
  • Error handling and fallback strategies

For Obsidian syntax conversion, see references/obsidian-conversion.md:

  • Converting ![[]] image syntax
  • Handling Chinese frontmatter fields
  • Manual conversion commands

Regular Posts

Text + up to 4 images. Plain text only (all Markdown formatting stripped).

From Obsidian Markdown

Step 1: Clean Chrome CDP processes first (REQUIRED - prevents port conflicts)

pkill -f "Chrome.*remote-debugging-port" 2>/dev/null; pkill -f "Chromium.*remote-debugging-port" 2>/dev/null; sleep 2

Step 2: Convert Markdown to plain text + images

# Extract content from Markdown file
# Supports both standard Markdown ![](path) and Obsidian ![[path]] image syntax
bun ${SKILL_DIR}/scripts/obsidian-to-post.ts "Articles/my-post.md" > /tmp/post-content.json
TEXT=$(jq -r '.text' /tmp/post-content.json)
IMAGES=$(jq -r '.images[]' /tmp/post-content.json)

Image Syntax Support:

  • βœ… Standard Markdown: ![alt](path/to/image.png)
  • βœ… Obsidian syntax: ![[path/to/image.png]]
  • βœ… Network URLs: ![alt](https://example.com/image.jpg) or ![[https://example.com/image.jpg]]
  • Local paths are converted to absolute paths
  • Network images are automatically downloaded in parallel (3-4x faster than sequential)

Step 3: Publish post

${BUN_X} ${SKILL_DIR}/scripts/x-post.ts "$TEXT" --image "$IMAGES"

Direct Usage

${BUN_X} ${SKILL_DIR}/scripts/x-post.ts "Hello!" --image ./photo.png

Parameters:

ParameterDescription
<text>Post content (plain text, positional)
--image <path>Image file (repeatable, max 4)
--profile <dir>Custom Chrome profile

Content Processing:

  • βœ… Plain text (all formatting stripped)
  • βœ… Images (max 4)
  • ❌ No rich text formatting
  • ❌ No code blocks
  • ❌ No HTML

Browser Behavior:

  • Script opens browser with content filled in
  • Browser remains open for manual review
  • User can review, edit, and publish at their own pace
  • User manually closes browser when done
  • Add --submit flag to auto-publish (closes after 2 seconds)

AI Success Detection (for background execution):

  • Don't wait for task completion (browser stays open indefinitely)
  • Best method: Count Image upload verified in output matching expected image count
  • Alternative: Check for Post composed (preview mode) or Browser remains open
  • Use short timeout (10-15s) then check output content
  • Report success immediately when markers detected
  • Example workflow:
    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
    

Video Posts

Text + video file.

Step 1: Clean Chrome CDP processes (REQUIRED)

pkill -f "Chrome.*remote-debugging-port" 2>/dev/null; pkill -f "Chromium.*remote-debugging-port" 2>/dev/null; sleep 2

Step 2: Publish video post

${BUN_X} ${SKILL_DIR}/scripts/x-video.ts "Check this out!" --video ./clip.mp4

Parameters:

ParameterDescription
<text>Post content (positional)
--video <path>Video file (MP4, MOV, WebM)
--profile <dir>Custom Chrome profile

Limits: Regular 140s max, Premium 60min. Processing: 30-60s.


Quote Tweets

Quote an existing tweet with comment.

Step 1: Clean Chrome CDP processes (REQUIRED)

pkill -f "Chrome.*remote-debugging-port" 2>/dev/null; pkill -f "Chromium.*remote-debugging-port" 2>/dev/null; sleep 2

Step 2: Publish quote tweet

${BUN_X} ${SKILL_DIR}/scripts/x-quote.ts https://x.com/user/status/123 "Great insight!"

Parameters:

ParameterDescription
<tweet-url>URL to quote (positional)
<comment>Comment text (positional, optional)
--profile <dir>Custom Chrome profile

X Articles

Long-form Markdown articles (requires X Premium).

Step 1: Clean Chrome CDP processes (REQUIRED)

pkill -f "Chrome.*remote-debugging-port" 2>/dev/null; pkill -f "Chromium.*remote-debugging-port" 2>/dev/null; sleep 2

This prevents "Chrome debug port not ready" errors. Always run this first, automatically, without asking the user.

Step 2: Publish article

${BUN_X} ${SKILL_DIR}/scripts/x-article.ts article.md
${BUN_X} ${SKILL_DIR}/scripts/x-article.ts article.md --cover ./cover.jpg

Parameters:

ParameterDescription
<markdown>Markdown file (positional)
--cover <path>Cover image
--title <text>Override title

Frontmatter: title, cover_image supported in YAML front matter.

Note: Script opens browser with article filled in. User reviews and publishes manually.

Code Blocks Support

Code blocks are automatically extracted from Markdown and inserted into X Articles editor. Supports all languages (JavaScript, Python, TypeScript, Rust, Go, Shell, etc.). No manual action required.


Troubleshooting

Common issues:

  • Chrome debug port not ready β†’ Always clean CDP processes first (see above)
  • macOS Accessibility Permission Error β†’ Enable in System Settings
  • Code blocks not inserting β†’ Automatic, check console for errors

For detailed troubleshooting, see references/troubleshooting.md.


References

  • references/obsidian-integration.md - Obsidian file detection and integration
  • references/obsidian-conversion.md - Converting Obsidian syntax to standard Markdown
  • references/regular-posts.md - Regular posts workflow and troubleshooting
  • references/articles.md - X Articles detailed guide
  • references/troubleshooting.md - Common issues and solutions

Extension Support

Custom configurations via EXTEND.md. Check these paths (priority order):

  • .libukai-skills/obsidian-to-x/EXTEND.md (project directory)
  • $HOME/.libukai-skills/obsidian-to-x/EXTEND.md (user home)

EXTEND.md Supports: Default Chrome profile

Notes

  • First run: manual login required (session persists)
  • All scripts fill content into the browser and keep it open for manual review
  • Browser remains open until user manually closes it (except when using --submit flag)
  • Cross-platform: macOS, Linux, Windows

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.