SuperAPI AI Directory

ray-x-article

Writing & research

View repository

Updated 10-15 22:37

About this skill

Ray X Article

Treat X Articles as a delivery backend, not a content source. The body is always based on the local Markdown; the browser is only responsible for creating or updating the draft, uploading the cover, and verifying the result.

Fixed boundaries

  1. Only process complete articles that have already passed ray-writer inspection; when content judgment is unstable, go back to the writing pipeline first.
  2. The cover must come from ray-cover, and the X Article uses the 5:2 final output; a 16:9 ordinary X share image cannot directly replace it.
  3. X has no public Article draft API. Use the browser or computer control capability available on the current host to operate the user's already logged-in backend; do not use the ordinary Post API or xurl post, and do not mistake a tool that can only read web pages for an operable browser.
  4. The endpoint of this Skill is fixed as a verified draft;Publish buttons and confirmation pop-ups are all outside the scope of operations. Public publishing must enter another explicit publishing task after draft acceptance.
  5. Before creation, check whether an article with the same name exists in Drafts; prefer opening and updating an existing draft, and do not create duplicates.
  6. Published Articles are not modification targets of this Skill. Do not enter Published editing; X will unpublish first, and this must be handled by another explicit task.
  7. kind: translation or kind: repost translated/adapted drafts have an extra authorization gate:source_permission is not granted or open-license , only produce the local delivery package and do not open the browser. The source block must enter the editor together with the body, and the original link must remain clickable. For the contract, see ray-writer/references/translation.md。

0. Determine authorization first

Before starting browser operations, write an internal determination based on the user's exact words in this round. This table and the determination rules are fully consistent with the ray main entry andray-wechat , and are not explained separately in this Skill:

Level What can be done Basis for determination
local_only Only produce the local delivery package, do not touch the X backend The user only says "take a look first" or "prepare the delivery package", or the whole sentence does not name a platform destination
draft_write Create or update an X Article draft and fully accept it The exact words in this round simultaneously includea specific platformanddestination, for example "save to the X Articles drafts" or "put it into the X backend"
Public publishing does not belong to the content production pipeline This determination never produces it; this Skill has no publish determination

Three determination rules:

  1. Only names a platform, with vague verbs—"push to X", "sync to two platforms", "list on the backend"—do not directly upgrade to draft_write. First finish the local delivery package, then ask clearly in one sentence: "The delivery package is ready. Do you want to write it into the X drafts now?" Only open the browser after receiving an affirmative answer. Neither write without authorization nor finish without saying anything.
  2. No platform destination is named at all— "Manuscript accepted OK", "proceed to the next stage", "go through the full publishing workflow" — all of these local_only, without asking and without writing.
  3. The user explicitly says "publish" or "make public"— still only go as far as the draft and acceptance, then explain that public publishing exceeds the boundary of this Skill; you must not merge preparing the draft and clicking Publish into a single continuous operation.

Publishing permission from a past task, permission from another platform, an already-logged-in state, or the button already being visible do not constitute authorization for this round. When in doubt, always fall back to local_only。

Before entering the browser, explain to the user that this session will stop at the draft and will not publish publicly.

1. Prepare the delivery package

Read the full body text, the finished manuscript package, and the cover manifest. Run:

python3 scripts/prepare_article.py --article <文章.md> --cover <x-article-cover.png> --out <临时交付包.json>

The script is responsible for removing the frontmatter and the first-level heading at the start of the body, generating plain-text and rich-text HTML, checking the title and body, confirming that long articles have sections and key points in bold, rejecting consecutive blank lines, confirming the cover is close to 5:2, verifying authorization and byline for translated pieces, and outputting the block count the editor should have, theh1/h2 count, the bold count, the first and last anchors, the image list, and the fingerprint. For ordered and unordered lists, put only the content into <li>, the original numbers or bullet symbols must be stripped, leaving the X editor to generate the single layer of list markers. If the check fails, go back to ray-writer or ray-cover to fix it; do not bypass it.

The numbers in the delivery package are all calculated according to editor semantics; use them directly when verifying, and do not go back and count the Markdown yourself:

  • expected_editor.block_count is Draft.js's block count; in a list, each <li> counts as a separate block.
  • The editor has only Heading(h1) and Subheading(h2) two levels; Markdown ## produces h1,### and deeper produces h2。
  • start_anchor / end_anchor is taken from the text actually displayed on the page after pasting HTML; for links keep only the anchor text.
  • images is the list of image positions; when there are no images in the body it is an empty array.

2. Enter X Articles

First read browser-capability.md, and choose from the current host the capability that can control a logged-in browser, upload local files, and inspect the visible page. Then read x-editor-contract.md, and locate the editor according to the verified visible text.

First read the article frontmatter:

  • When x_article_draft_url already exists, open that URL directly, verify the title, and then update the original draft.
  • When the status is draft-needs-cover , only add the cover and re-verify; do not rewrite the body or create a second draft.
  • When the status is already draft, but the user mentions past failures, take the currently visible status in the backend as authoritative: first verify the original draft, and only re-upload the cover if it is indeed missing; do not overwrite directly based on the old account.
  • Only when there is no draft URL, open https://x.com/compose/articles, and confirm that the page has Articles、Drafts、Published, and that the current account is logged in and has the Write entry point; then check whether Drafts contains an article with the same name, and if so open the original draft instead of creating a new one.

Only after completing the duplicate check, proceed to Write. Entering the edit page immediately generates a blank draft, so if something fails afterward, either keep it and record the address for recovery, or confirm that it is still completely blank and then delete it. When encountering permission failure, disconnection, or recovery of an old draft, read recovery-runbook.md。

3. Write the draft

Execute in the following order:

  1. Upload the 5:2 cover from the delivery package: read the page to get a reference to the file input element, and use a dedicated file upload action to give it the absolute path,do not click Choose File(It pops up a native dialog and will freeze). After Edit media appears, click Apply, then use the actual cover display and the appearance of Remove photo as the upload success signal.
  2. In Add a title , fill in the title and verify it character by character.
  3. Write body_html from the delivery package as HTML andbody as plain text to the browser clipboard at the same time, then select all in the body textbox and paste. This lets the editor directly generate normal paragraphs, headings, lists, links, and bold text without inserting blank paragraphs.
  4. After pasting, check that no Markdown symbols remain, and compare the page block count, blank block count,h1 count,h2 count, and bold count item by item against the delivery package's expected_editor . Fall back to plain text only when HTML paste is unavailable, then manually restore the formatting.
  5. Spot-check the first and last item of each ordered list: the editor should show only one level of automatic numbering, and the list body must not start again with 1.、2. or 1、 .
  6. After the block count check passes, insert images from front to back according to the delivery package's images list: use after_block and after_text to locate the insertion point, and confirm one by one that the inserted image is the one in the list. Inserting images changes the page block count, so the order cannot be reversed. Skip this step whenimages is empty.
  7. Wait for Last saved just now to appear on the page, or for an equivalent saved state.

When the cover upload is rejected, do not keep trying to bypass it, and do not create a new draft. First use recovery-runbook.md 's "cover upload rejected" to distinguish whether the path is not shared or the wrong control was clicked: for the former, record draft-needs-cover and the current URL, give the user the cover's absolute path, and ask the user to share that directory with this session; for the latter, retry using the correct upload path. After receiving confirmation, add only the cover from the original URL.

After filling in the body, do not enter the Publish flow. Do not click the first Publish to "take a look at the confirmation dialog"; the dialog itself is already part of the public publishing flow.

4. Verify the draft

Complete the following checks:

  • The title matches the delivery package exactly.
  • The page word count is not zero, the body block count matches expected_editor.block_count (verify before inserting images), the first block starts with start_anchor , and the last block ends with end_anchor .
  • There are no blank paragraphs between paragraphs;h1、h2 and the bold count match the delivery package.
  • images Every image in the list has been inserted, the positions match after_block , and the images display normally.
  • The cover is displayed, and the title or core metaphor has not been cropped out.
  • After opening Preview , the title, paragraphs, cover, and author information are all normal.

After the preview check, return to the edit page and confirm again that the cover is still there, the body formatting has not changed, and the save time has been updated. If the check fails, fix it and verify again; do not hand a problematic draft to the user to troubleshoot on their own.

5. Write back to the knowledge base

After verification passes, run:

python3 scripts/record_draft.py --article <文章.md> --url <草稿地址> --cover <x-article-cover.png> --content-sha256 <交付包中的指纹>

It will record the following in the article frontmatter:

  • x_article_status: draft
  • x_article_draft_url
  • x_article_saved_at
  • x_article_cover
  • x_article_content_sha256

These fields are not just records:x_article_status: draft plus x_article_saved_at is the gate for the collection pipeline's (50-系统/40-自动化/知识采集/knowledge_ingest.py, one round every 30 minutes) automatic publish detection. After a person clicks publish on the platform, the pipeline will, within 72 hours from the save time, automatically compare against the Article post on its own timeline to confirm publication, then flip the draft's x_article_status to published, and write x_article_url(public URL),x_article_published_at and published_file, archive the final version to 40-发布/, and write it back to the draft package. Therefore:

  • Detection matches by article title (exact match takes priority; if the title is slightly changed in the editor before publishing, similarity serves as a fallback); if the title is changed significantly at publish time, automatic detection may not catch it, in which case use the "Register Publication" form in the knowledge workbench to register it manually.
  • draft-needs-cover does not enter automatic detection; re-recording it as draft will refresh x_article_saved_at, which is equivalent to reopening the 72-hour detection window.
  • Drafts published more than 72 hours later are no longer polled and likewise go through the "Register Publication" form.

When the cover has not yet been uploaded due to external reasons such as browser permissions, first use --status draft-needs-cover to record a recoverable state; after completing and verifying the cover, it must be re-recorded as draft。

The local article remains in 10-创作/30-文章草稿/. This Skill does not copy or move it to 40-发布/10-X长文/, nor does it change the status to published. Post-publication archiving and status flipping are handled by the automatic detection above, and when detection is uncertain, the workbench's "Register Publication" form provides manual fallback—neither is an action of this Skill.

Delivery requirements

Provide the user with the local article, the 5:2 cover, and the X draft link. Only state what has been saved and verified, and whether there are any formats requiring manual review; finally, state separately and explicitly that "this is a draft and has not been publicly published." If the user's original words include "publish," explain that this Skill has stopped at the draft stage, and that public publishing requires a separate next step.