SuperAPI AI Directory

yichen-x-article-draft-uploader

Writing & research

View repository

Updated 10-16 00:22

About this skill

X Article Draft Uploader

Core Principles

Only create drafts. Unless the user explicitly confirms it can be publicly published, do not click X's final 发布 button.

Use an independent Playwright browser session; do not seize the Chrome window the user is currently using. The Chrome login state can be reused, but only via a temporarily exported Playwright cookie JSON.

Quick Start

  1. If /tmp/x_current_cookies.json does not exist or the login state is invalid, first export the current X cookies:
python3 ~/.codex/skills/yichen-x-article-draft-uploader/scripts/export_x_cookies_from_chrome.py --output /tmp/x_current_cookies.json
  1. Before actually touching X, first dry-run parse the article to confirm the cover, the number of body images, and the anchors:
python3 ~/.codex/skills/yichen-x-article-draft-uploader/scripts/upload_markdown_to_x_article.py \
  "/absolute/path/to/article.md" \
  --cookies-json /tmp/x_current_cookies.json \
  --dry-run

If the dry-run warns that "the article's first valid content is not an image," stop first and remind the user: it is recommended to add a cover image at the very beginning of the article. Do not continue uploading. Only when the user explicitly refuses to add a cover and asks to continue uploading a draft without a cover, add --allow-no-cover:

python3 ~/.codex/skills/yichen-x-article-draft-uploader/scripts/upload_markdown_to_x_article.py \
  "/absolute/path/to/article.md" \
  --cookies-json /tmp/x_current_cookies.json \
  --allow-no-cover
  1. Create a clean new X Article draft and upload:
python3 ~/.codex/skills/yichen-x-article-draft-uploader/scripts/upload_markdown_to_x_article.py \
  "/absolute/path/to/article.md" \
  --cookies-json /tmp/x_current_cookies.json

The script will output these result files:

  • Draft URL:/tmp/x_article_upload_url.txt
  • Validation result JSON:/tmp/x_article_upload_result.json
  • Final screenshot:/tmp/x_article_final_uploaded.png

Workflow

  1. Use this Skill's built-in scripts/parse_markdown.py to parse Markdown.
  2. Check whether the article's first valid content is an image. If it is not an image, by default interrupt the upload and remind the user to add a cover image; only when the user explicitly refuses to add a cover and asks to continue, use --allow-no-cover to skip cover upload.
  3. Treat the first image at the very beginning of the article as the cover image. When using --allow-no-cover , do not upload a cover; all images in the article are treated as body images.
  4. From the original Markdown, read the line before each body image as the image insertion anchor. Pay special attention in list scenarios: use the actual previous line, for example Git 变化。, not the longer fallback assembled from preceding list items.
  5. Launch a brand-new Playwright Chromium context and add the X cookies.
  6. Open https://x.com/compose/articles, click create, and record the newly generated /compose/articles/edit/... URL。
  7. Upload the cover via the file input in the cover area, then click X's 应用. If this step is skipped, X will leave a media-edit mask blocking the editor, and the cover will not actually be saved.
  8. Fill in the title, and paste the rich HTML body into [data-testid="composer"]。
  9. Insert body images from back to front. Process each image in this order:
    • Find the highest-priority anchor in the current editor.
    • Click at the end of that paragraph.
    • Press End, then press Enter。
    • Paste the image file via a clipboard paste event.
    • Wait for the media count detected on the page to increase before continuing to the next image.
  10. Wait for X autosave to complete, then validate the title, the beginning/end of the body, the absence of MPH_MARKER, and confirm that the total media count equals 封面数 + expected_image_count。

Common Blockers

  • If X redirects to /login, the login state is invalid; re-export the cookies.
  • If the article does not start with an image, by default stop the upload. Remind the user to add a cover image; only after the user explicitly refuses, use --allow-no-cover Continue.
  • If the editor is blocked by an overlay after uploading the cover, find the 应用 button and click it.
  • Do not use a hidden file input directly for body images. It may point to the cover uploader and cause the cover to be replaced.
  • Do not only look at the media count. Especially for images after the list, check whether the anchor is correct. The script will record in the result JSON anchor_used and expected_anchor。
  • If a run is only partially successful but the image positions are wrong, prioritize creating a clean new draft and rerunning rather than forcing fixes on the old draft.

Script description

  • upload_markdown_to_x_article.py --dry-run is a safety check and will not open X.
  • --allow-no-cover is only used when the user explicitly refuses to add a cover image; it skips the cover upload and inserts all images as body images.
  • The upload script requires Python Playwright and a valid X cookie JSON.
  • The Markdown parser is already built into the current Skill and does not depend on the old x-article-publisher Skill。
  • The cookie export script only reads local Chrome cookies and writes them to the specified temporary Playwright cookie file; the Skill itself does not save any cookies.