Post to X (Twitter)
Posts text, images, videos, and long-form articles to X via a real Chrome browser.
In Codex, do not conflate these browser paths:
- Codex Chrome plugin /
@chrome/ Chrome Extension: use the bundledchrome:Chromeskill and its Node REPL browser client. This is required whenever the user says "Codex Chrome plugin", "Codex 自带的 Chrome 插件",@chrome, or similar. - Chrome Computer Use: use
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. - CDP script mode: use only as a fallback when the selected mode is unavailable or the user explicitly asks for CDP/script mode.
Script Directory
Important: All scripts are located in the scripts/ subdirectory of this skill.
Agent Execution Instructions:
- Determine this SKILL.md file's directory path as
{baseDir} - Script path =
{baseDir}/scripts/<script-name>.ts - Replace all
{baseDir}in this document with the actual path - Resolve
${BUN_X}runtime: ifbuninstalled →bun; ifnpxavailable →npx -y bun; else suggest installing bun
Script 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 |
scripts/paste-from-clipboard.ts | Send real paste keystroke |
scripts/check-paste-permissions.ts | Verify environment & permissions |
Execution Mode Selection (Required)
Choose exactly one mode before interacting with X:
- If the user explicitly asks for the Codex Chrome plugin,
@chrome, the Chrome extension, or "Codex 自带的 Chrome 插件", use Codex Chrome Plugin Mode. Do not call Computer Use first. - If the user explicitly asks for Chrome Computer Use, use Chrome Computer Use Mode. Do not fall back to CDP, Playwright, the in-app Browser, or the Chrome plugin without telling the user and getting approval.
- If the user explicitly asks for CDP/script mode, use CDP Script Mode.
- Otherwise, prefer Chrome Computer Use Mode. For Markdown X Articles with local content images, use the tested X editor flow: insert each body image from the toolbar (
Insert->Media-> dialog icon buttonAdd 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.
Codex Chrome Plugin Mode
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
- Load the
chrome:Chromeskill before browser work. - Use
tool_searchfornode_repl jsif the Node REPLjstool is not already visible. - Initialize the Chrome browser client exactly as the Chrome skill specifies, then run a lightweight call such as
browser.user.openTabs()to verify the extension connection. - If the first lightweight call fails, wait 2 seconds and retry once. If it still fails, follow the Chrome skill's extension checks and recovery steps. If checks pass but communication still fails, ask the user before opening a new Chrome window. Do not switch to Computer Use or CDP silently.
General rules
- Use the Chrome plugin's
browser.tabs.*,tab.playwright.*,tab.cua.*, and file chooser APIs for X UI actions. - Shell commands are allowed for Markdown preprocessing and rich-HTML clipboard preparation. For X Article body images, do not rely on image clipboard paste; use the editor's
Insert->Mediaupload flow. - If a file upload fails with
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. - If the Chrome plugin reports
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. - Never click
Publish,Post, or any externally visible submit action without explicit final confirmation from the user in the current conversation.
X Articles
- Convert Markdown and keep the image map:
${BUN_X} {baseDir}/scripts/md-to-html.ts article.md --save-html /tmp/x-article-body.html > /tmp/x-article.json - Read the JSON output for
title,coverImage, andcontentImages(placeholder→localPath). - Open or create the article draft at
https://x.com/compose/articles. - Upload the cover with the Chrome plugin file chooser flow. If upload is blocked by extension permissions, stop and report the exact permission fix above.
- Fill the title, then copy rich HTML:
${BUN_X} {baseDir}/scripts/copy-to-clipboard.ts html --file /tmp/x-article-body.html - Paste into the article body with a real paste keystroke through the Chrome plugin. On macOS use
Meta+V. - Verify the editor text contains the article body and
XIMGPH_placeholders. Do not rely ontab.clipboard.readText()as proof of the system clipboard after shell clipboard writes; on macOS verify withpbpasteif needed. - For each
contentImagesitem in placeholder order:- Locate the visible placeholder text (
XIMGPH_N) and click it to place the caret there. - Open the toolbar menu
Insert->Media. - In the modal, click the icon button with
aria-label="Add photos or video"; do not click the text/dropzone or hidden file input. - Use the file chooser to upload that image's
localPath. - After the image appears, if
XIMGPH_Nremains above it, select exactly that placeholder and pressDeletefirst. UseBackspaceonly ifDeletefails and the selected text is confirmed to be exactly the placeholder. - Verify the placeholder count for that
XIMGPH_Nis0.
- Locate the visible placeholder text (
- Open Preview and verify title, cover, body, links, and images.
- Ask for explicit confirmation before clicking
Publish.
Preferences (EXTEND.md)
Check 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
Prerequisites
- Google Chrome or Chromium
bunruntime- First run: log in to X manually (session saved)
Pre-flight Check (Optional)
Before first use, suggest running the environment check. User can skip if they prefer.
${BUN_X} {baseDir}/scripts/check-paste-permissions.ts
Checks: 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 | Ensur |