Posts content and articles to X (Twitter). Supports regular posts with images/videos and X Articles (long-form Markdown). In Codex, honor explicit requests for the Codex Chrome plugin/@chrome by using the Chrome Extension workflow; otherwise use Chrome Computer Use when available and fall back to real Chrome CDP scripts only when allowed. Use when user asks to "post to X", "tweet", "publish to Twitter", or "share on X".
Use the skills CLI to install this skill with one command. Auto-detects all installed AI assistants.
Method 1 - skills CLI
npx skills i JimLiu/baoyu-skills/skills/baoyu-post-to-xMethod 2 - openskills (supports sync & update)
npx openskills install JimLiu/baoyu-skillsAuto-detects Claude Code, Cursor, Codex CLI, Gemini CLI, and more. One install, works everywhere.
Installation Path
Download and extract to one of the following locations:
No setup needed. Let our cloud agents run this skill for you.
Select Provider
Select Model
Best for coding tasks
Environment setup included
Posts text, images, videos, and long-form articles to X via a real Chrome browser.
In Codex, do not conflate these browser paths:
@chrome / Chrome Extension: use the bundled chrome:Chrome skill and its Node REPL browser client. This is required whenever the user says "Codex Chrome plugin", "Codex 自带的 Chrome 插件", @chrome, or similar.mcp__computer_use__.* against the visible Google Chrome UI only when the user asks for Computer Use or no Chrome-plugin preference is stated and Computer Use is available.Important: All scripts are located in the scripts/ subdirectory of this skill.
Agent Execution Instructions:
{baseDir}{baseDir}/scripts/<script-name>.ts{baseDir} in this document with the actual path${BUN_X} runtime: if bun installed → bun; if npx available → npx -y bun; else suggest installing bunScript Reference:
| Script | Purpose |
|---|---|
scripts/x-browser.ts | Regular posts (text + images), CDP fallback |
scripts/x-video.ts | Video posts (text + video), CDP fallback |
scripts/x-quote.ts | Quote tweet with comment, CDP fallback |
scripts/x-article.ts | Long-form article publishing (Markdown), CDP fallback |
scripts/md-to-html.ts | Markdown → HTML conversion |
scripts/copy-to-clipboard.ts | Copy content to clipboard |
Choose exactly one mode before interacting with X:
@chrome, the Chrome extension, or "Codex 自带的 Chrome 插件", use Codex Chrome Plugin Mode. Do not call Computer Use first.Insert -> Media -> dialog icon button Add photos or video) at its placeholder, then delete the placeholder text. Use CDP Script Mode only when the selected browser-control mode is unavailable or the UI upload/selection flow is unreliable.Never use the in-app Browser for X publishing workflows.
Use this mode whenever the user requests the Codex Chrome plugin, @chrome, or the Chrome Extension path. This uses the user's real Chrome profile and X login through the bundled Chrome plugin, not Computer Use and not CDP.
Setup
chrome:Chrome skill before browser work.tool_search for node_repl js if the Node REPL js tool is not already visible.browser.user.openTabs() to verify the extension connection.General rules
browser.tabs.*, tab.playwright.*, tab.cua.*, and file chooser APIs for X UI actions.Insert -> Media upload flow.Not allowed, tell the user: To enable file upload, go to chrome://extensions in Chrome, click Details under the Codex extension, and enable "Allow access to file URLs." See https://developers.openai.com/codex/app/chrome-extension#upload-files for details.native pipe is closed, retry the lightweight browser call once after 2 seconds, then run the Chrome skill health checks. If Chrome is running, the extension is enabled, and the native host manifest is correct, ask permission to open a new Chrome window and retry. Do not keep sending browser actions through the broken pipe.Publish, Post, or any externally visible submit action without explicit final confirmation from the user in the current conversation.X Articles
${BUN_X} {baseDir}/scripts/md-to-html.ts article.md --save-html /tmp/x-article-body.html > /tmp/x-article.jsontitle, coverImage, and contentImages (placeholder → localPath).https://x.com/compose/articles.${BUN_X} {baseDir}/scripts/copy-to-clipboard.tsCheck EXTEND.md in priority order — the first one found wins:
| Priority | Path | Scope |
|---|---|---|
| 1 | .baoyu-skills/baoyu-post-to-x/EXTEND.md | Project |
| 2 | ${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-post-to-x/EXTEND.md | XDG |
| 3 | $HOME/.baoyu-skills/baoyu-post-to-x/EXTEND.md | User home |
If none found, use defaults.
EXTEND.md supports: Default Chrome profile
bun runtimeBefore first use, suggest running the environment check. User can skip if they prefer.
${BUN_X} {baseDir}/scripts/check-paste-permissions.tsChecks: Chrome, profile isolation, Bun, Accessibility, clipboard, paste keystroke, Chrome conflicts.
If any check fails, provide fix guidance per item:
| Check | Fix |
|---|---|
| Chrome | Install Chrome or set X_BROWSER_CHROME_PATH env var |
| Profile dir | Shared profile at baoyu-skills/chrome-profile (see CLAUDE.md Chrome Profile section) |
| Bun runtime | brew install oven-sh/bun/bun (macOS) or npm install -g bun |
| Accessibility (macOS) | System Settings → Privacy & Security → Accessibility → enable terminal app |
| Clipboard copy | Ensure Swift/AppKit available (macOS Xcode CLI tools: xcode-select --install) |
| Paste keystroke (macOS) | Same as Accessibility fix above |
references/regular-posts.md for manual workflow, troubleshooting, and technical detailsreferences/articles.md for long-form article publishing guideUse this mode when the user explicitly asks for Chrome Computer Use, or when no Chrome-plugin preference is stated and Codex can control Google Chrome with Computer Use. This uses the user's existing Chrome window, cookies, login, extensions, and X session.
General rules:
get_app_state for Google Chrome.Publish, Post, or any externally visible submit action without an explicit final confirmation from the user in the current conversation.Regular posts:
https://x.com/compose/post.${BUN_X} {baseDir}/scripts/copy-to-clipboard.ts image /absolute/path/to/image.pngsuper+v on macOS, control+v on Windows/Linux), then wait until X finishes uploading media.Post.Video posts:
https://x.com/compose/post.Post.Quote tweets:
Post.X Articles:
${BUN_X} {baseDir}/scripts/md-to-html.ts article.md --save-html /tmp/x-article-body.html > /tmp/x-article.jsontitle, coverImage, and contentImages (placeholder → localPath).https://x.com/compose/articles, create or open the draft, upload the cover if present, and fill the title.${BUN_X} {baseDir}/scripts/copy-to-clipboard.ts htmlIf Computer Use selection, toolbar upload, or file-picker control becomes unreliable, stop and report the blocker instead of switching to the Chrome plugin or CDP silently.
Use the script sections below only when the selected browser-control mode is unavailable, unreliable, or explicitly not requested. These scripts launch or reuse a real Chrome instance via CDP and keep the browser open for review.
Do not use CDP Script Mode when the user explicitly requires the Codex Chrome plugin or Chrome Computer Use unless the user approves the fallback after you explain the blocker.
Unless the user explicitly specifies the post type:
${BUN_X} {baseDir}/scripts/x-browser.ts "Hello!" --image ./photo.pngParameters:
| Parameter | Description |
|---|---|
<text> | Post content (positional) |
--image <path> | Image file (repeatable, max 4) |
--profile <dir> | Custom Chrome profile |
Note: Script opens browser with content filled in. User reviews and publishes manually.
Codex mode note: If the user explicitly requested the Codex Chrome plugin, use Codex Chrome Plugin Mode. Otherwise, if Chrome Computer Use is enabled, use Chrome Computer Use Mode instead of running x-browser.ts.
Text + video file.
${BUN_X} {baseDir}/scripts/x-video.ts "Check this out!" --video ./clip.mp4Parameters:
| Parameter | Description |
|---|---|
<text> | Post content (positional) |
--video <path> | Video file (MP4, MOV, WebM) |
--profile <dir> | Custom Chrome profile |
Note: Script opens browser with content filled in. User reviews and publishes manually.
Codex mode note: If the user explicitly requested the Codex Chrome plugin, use Codex Chrome Plugin Mode. Otherwise, if Chrome Computer Use is enabled, use Chrome Computer Use Mode instead of running x-video.ts.
Limits: Regular 140s max, Premium 60min. Processing: 30-60s.
Quote an existing tweet with comment.
${BUN_X} {baseDir}/scripts/x-quote.ts https://x.com/user/status/123 "Great insight!"Parameters:
| Parameter | Description |
|---|---|
<tweet-url> | URL to quote (positional) |
<comment> | Comment text (positional, optional) |
--profile <dir> | Custom Chrome profile |
Note: Script opens browser with content filled in. User reviews and publishes manually.
Codex mode note: If the user explicitly requested the Codex Chrome plugin, use Codex Chrome Plugin Mode. Otherwise, if Chrome Computer Use is enabled, use Chrome Computer Use Mode instead of running x-quote.ts.
Long-form Markdown articles (requires X Premium).
${BUN_X} {baseDir}/scripts/x-article.ts article.md
${BUN_X} {baseDir}/scripts/x-article.ts article.md --cover ./cover.jpgParameters:
| Parameter | Description |
|---|---|
<markdown> | Markdown file (positional) |
--cover <path> | Cover image |
--title <text> | Override title |
Frontmatter: title, cover_image supported in YAML front matter.
Codex mode note: If the user explicitly requested the Codex Chrome plugin, follow Codex Chrome Plugin Mode above. If the user explicitly requested Chrome Computer Use, follow Chrome Computer Use Mode. Otherwise, prefer Chrome Computer Use; for Markdown articles with local content images, use the toolbar Insert -> Media image-upload workflow before falling back to x-article.ts in CDP Script Mode.
CDP fallback note: The script opens browser with article filled in. User reviews and publishes manually unless --submit is used.
Publish safety: Do not use --submit or click Publish unless the user explicitly confirms the final public publish action.
Post-Composition Check: The script automatically verifies after all images are inserted:
XIMGPH_ placeholders in editor contentIf the check fails (warnings in output), alert the user with the specific issues before they publish.
CDP fallback only: if a script fails with Chrome debug port not ready or Unable to connect, kill existing Chrome CDP instances first, then retry:
pkill -f "Chrome.*remote-debugging-port" 2>/dev/null; pkill -f "Chromium.*remote-debugging-port" 2>/dev/null; sleep 2Important: This should be done automatically — when encountering this error, kill Chrome CDP instances and retry the command without asking the user.
--submit is explicitly usedCustom configurations via EXTEND.md. See Preferences section for paths and supported options.
scripts/paste-from-clipboard.ts | Send real paste keystroke |
scripts/check-paste-permissions.ts | Verify environment & permissions |
Meta+V.XIMGPH_ placeholders. Do not rely on tab.clipboard.readText() as proof of the system clipboard after shell clipboard writes; on macOS verify with pbpaste if needed.contentImages item in placeholder order:
XIMGPH_N) and click it to place the caret there.Insert -> Media.aria-label="Add photos or video"; do not click the text/dropzone or hidden file input.localPath.XIMGPH_N remains above it, select exactly that placeholder and press Delete first. Use Backspace only if Delete fails and the selected text is confirmed to be exactly the placeholder.XIMGPH_N is 0.Publish.| Paste keystroke (Linux) | Install xdotool (X11) or ydotool (Wayland) |
contentImages entry in placeholder order:
XIMGPH_3 and click it to set the insertion point.Insert dropdown, choose Media, then click the modal's icon button labeled Add photos or video.localPath.Delete first. Use Backspace only if Delete fails and the selected text is confirmed to be exactly the placeholder.XIMGPH_ placeholders remain and the expected images appear.Publish.