spacezephyr/read-buddy · Archived

read-x-markdown

Converts X (Twitter) tweets and articles to markdown with YAML front matter. Uses reverse-engineered API requiring user consent. Use when user mentions "X to markdown", "tweet to markdown", "save tweet", or provides x.com/twitter.com URLs for conversion.

First seen Jul 11, 2026

Installation

$ npx skills add spacezephyr/read-buddy --skill read-x-markdown

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from spacezephyr/read-buddy · top by installs.

npx skills add spacezephyr/read-buddy

Browse all from spacezephyr/read-buddy

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 60
License MIT
Default branch main
Open issues 0
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 8,695 B
  • docs SUMMARY.md 277 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 4 installs

SKILL.md

X to Markdown

Converts X content to markdown:

  • Tweets/threads → Markdown with YAML front matter
  • X Articles → Full content extraction

Script Directory

Scripts located in scripts/ subdirectory.

Path Resolution:

  1. SKILL_DIR = this SKILL.md's directory
  2. Script path = ${SKILL_DIR}/scripts/main.ts

Consent Requirement

Before any conversion, check and obtain consent.

Consent Flow

Step 1: Check consent file

# macOS
cat ~/Library/Application\ Support/read-buddy/x-to-markdown/consent.json

# Linux
cat ~/.local/share/read-buddy/x-to-markdown/consent.json

Step 2: If accepted: true and disclaimerVersion: "1.0" → print warning and proceed:

Warning: Using reverse-engineered X API. Accepted on: <acceptedAt>

Step 3: If missing or version mismatch → display disclaimer:

DISCLAIMER

This tool uses a reverse-engineered X API, NOT official.

Risks:
- May break if X changes API
- No guarantees or support
- Possible account restrictions
- Use at your own risk

Accept terms and continue?

Use AskUserQuestion with options: "Yes, I accept" | "No, I decline"

Step 4: On accept → create consent file:

{
  "version": 1,
  "accepted": true,
  "acceptedAt": "<ISO timestamp>",
  "disclaimerVersion": "1.0"
}

Step 5: On decline → output "User declined. Exiting." and stop.

Preferences (EXTEND.md)

Use Bash to check EXTEND.md existence (priority order):

# Check project-level first
test -f .read-buddy/read-x-markdown/EXTEND.md && echo "project"

# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
test -f "$HOME/.read-buddy/read-x-markdown/EXTEND.md" && echo "user"

┌────────────────────────────────────────────────────────────┬───────────────────┐ │ Path │ Location │ ├────────────────────────────────────────────────────────────┼───────────────────┤ │ .read-buddy/read-x-markdown/EXTEND.md │ Project directory │ ├────────────────────────────────────────────────────────────┼───────────────────┤ │ $HOME/.read-buddy/read-x-markdown/EXTEND.md │ User home │ └────────────────────────────────────────────────────────────┴───────────────────┘

┌───────────┬───────────────────────────────────────────────────────────────────────────┐ │ Result │ Action │ ├───────────┼───────────────────────────────────────────────────────────────────────────┤ │ Found │ Read, parse, apply settings │ ├───────────┼───────────────────────────────────────────────────────────────────────────┤ │ Not found │ MUST run first-time setup (see below) — do NOT silently create defaults │ └───────────┴───────────────────────────────────────────────────────────────────────────┘

EXTEND.md Supports: Download media by default | Default output directory

First-Time Setup (BLOCKING)

CRITICAL: When EXTEND.md is not found, you MUST use AskUserQuestion to ask the user for their preferences before creating EXTEND.md. NEVER create EXTEND.md with defaults without asking. This is a BLOCKING operation — do NOT proceed with any conversion until setup is complete.

Use AskUserQuestion with ALL questions in ONE call:

Question 1 — header: "Media", question: "How to handle images and videos in tweets?"

  • "Ask each time (Recommended)" — After saving markdown, ask whether to download media
  • "Always download" — Always download media to local imgs/ and videos/ directories
  • "Never download" — Keep original remote URLs in markdown

Question 2 — header: "Output", question: "Default output directory?"

  • "x-to-markdown (Recommended)" — Save to ./x-to-markdown/{username}/{tweet-id}.md
  • (User may choose "Other" to type a custom path)

Question 3 — header: "Save", question: "Where to save preferences?"

  • "User (Recommended)" — ~/.read-buddy/ (all projects)
  • "Project" — .read-buddy/ (this project only)

After user answers, create EXTEND.md at the chosen location, confirm "Preferences saved to [path]", then continue.

Full reference: [references/config/first-time-setup.md](references/config/first-time-setup.md)

Supported Keys

Key Default Values Description
download_media ask ask / 1 / 0 ask = prompt each time, 1 = always download, 0 = never
defaultoutputdir empty path or empty Default output directory (empty = ./x-to-markdown/)

Value priority:

  1. CLI arguments (--download-media, -o)
  2. EXTEND.md
  3. Skill defaults

Usage

npx -y bun ${SKILL_DIR}/scripts/main.ts <url>
npx -y bun ${SKILL_DIR}/scripts/main.ts <url> -o output.md
npx -y bun ${SKILL_DIR}/scripts/main.ts <url> --download-media
npx -y bun ${SKILL_DIR}/scripts/main.ts <url> --json

Options

Option Description
<url> Tweet or article URL
-o <path> Output path
--json JSON output
--download-media Download image/video assets to local imgs/ and videos/, and rewrite markdown links to local relative paths
--login Refresh cookies only

Supported URLs

  • https://x.com/<user>/status/<id>
  • https://twitter.com/<user>/status/<id>
  • https://x.com/i/article/<id>

Output

---
url: "https://x.com/user/status/123"
author: "Name (@user)"
tweetCount: 3
coverImage: "https://pbs.twimg.com/media/example.jpg"
---

Content...

File structure: x-to-markdown/{username}/{tweet-id}.md

When --download-media is enabled:

  • Images are saved to imgs/ next to the markdown file
  • Videos are saved to videos/ next to the markdown file
  • Markdown media links are rewritten to local relative paths

Media Download Workflow

Based on download_media setting in EXTEND.md:

Setting Behavior
1 (always) Run script with --download-media flag
0 (never) Run script without --download-media flag
ask (default) Follow the ask-each-time flow below

Ask-Each-Time Flow

  1. Run script without --download-media → markdown saved
  2. Check saved markdown for remote media URLs (https:// in image/video links)
  3. If no remote media found → done, no prompt needed
  4. If remote media found → use AskUserQuestion:

- header: "Media", question: "Download N images/videos to local files?" - "Yes" — Download to local directories - "No" — Keep remote URLs

  1. If user confirms → run script again with --download-media (overwrites markdown with localized links)

Authentication

  1. Environment variables (preferred): XAUTHTOKEN, X_CT0
  2. Chrome login (fallback): Auto-opens Chrome, caches cookies locally

Extension Support

Custom configurations via EXTEND.md. See Preferences section for paths and supported options.