| name | x-schedule-post |
| description | Schedule a post on X (Twitter) and verify it was successfully scheduled. Use this when the task is specifically about scheduling and scheduled-post verification; prefer x-compose-post for general post creation, replies, quote posts, or mixed posting workflows. |
| compatibility | Requires ai-chrome-pilot server (npx tsx src/index.ts) and Google Chrome installed |
X (Twitter) Schedule Post
Schedule a post on X via ai-chrome-pilot and verify it appears in the scheduled posts list.
Treat this as the schedule-focused variant of x-compose-post. If the user wants a normal post, reply, or quote post, use x-compose-post instead.
Prerequisites
- ai-chrome-pilot server is running
- User is logged in to X (if not, run the
x-login skill first)
- Prefer
HEADLESS=0 for real scheduling flows so the visible composer state can be inspected
Required inputs
- Post text: The text to post
- Scheduled date/time: Year, month, day, hour, and minute
- Image (optional): An image to attach
Default resolution rules:
- Use
default unless the user explicitly requested another profile
- If post text and the full scheduled date/time are already provided, execute directly without an extra confirmation step
- Ask follow-up questions only when required inputs are missing
Steps
1. Verify server is running
curl -s http://127.0.0.1:3333/health
If not running, start it with the resolved profile:
HEADLESS=0 PROFILE_NAME=<profile_name> npx tsx src/index.ts &
sleep 3 && curl -s http://127.0.0.1:3333/health
2. Navigate to X home
curl -s -X POST http://127.0.0.1:3333/goto \
-H 'Content-Type: application/json' \
-d '{"url":"https://x.com"}'
After sleep 2, take a screenshot to confirm the user is logged in.
3. Enter post text safely
Use /snapshot to find the post text box ref.
curl -s http://127.0.0.1:3333/snapshot
Look for textbox "ポスト本文" (Post text), click it, then treat /act type only as an initial convenience path.
curl -s -X POST http://127.0.0.1:3333/act \
-H 'Content-Type: application/json' \
-d '{"ref":"<textbox_ref>","action":"click"}'
For scheduling that will actually be submitted, prefer the same text-entry strategy as x-compose-post:
- connect to the existing Chrome instance with
Playwright over CDP
- enter text with
page.keyboard.type()
- verify
[data-testid="tweetTextarea_0"] exactly matches the intended text before opening the schedule dialog
Do not rely on the visible composer alone. X can show an enabled action state while the actual composer DOM is still out of sync.
4. Open the schedule dialog
Click button "ポストを予約" (Schedule post).
curl -s -X POST http://127.0.0.1:3333/act \
-H 'Content-Type: application/json' \
-d '{"ref":"<schedule_button_ref>","action":"click"}'
After sleep 1, use /snapshot to inspect the schedule dialog elements.
5. Set the date and time
Use the /act select action on each combobox in the dialog. Add sleep 1 between each operation.
curl -s -X POST http://127.0.0.1:3333/act \
-H 'Content-Type: application/json' \
-d '{"ref":"<month_combobox_ref>","action":"select","values":["<N>月"]}'
curl -s -X POST http://127.0.0.1:3333/act \
-H 'Content-Type: application/json' \
-d '{"ref":"<day_combobox_ref>","action":"select","values":["<DD>"]}'
curl -s -X POST http://127.0.0.1:3333/act \
-H 'Content-Type: application/json' \
-d '{"ref":"<year_combobox_ref>","action":"select","values":["<YYYY>"]}'
curl -s -X POST http://127.0.0.1:3333/act \
-H 'Content-Type: application/json' \
-d '{"ref":"<hour_combobox_ref>","action":"select","values":["<HH>"]}'
curl -s -X POST http://127.0.0.1:3333/act \
-H 'Content-Type: application/json' \
-d '{"ref":"<minute_combobox_ref>","action":"select","values":["<MM>"]}'
6. Confirm the date/time change
After setting the date and time, click the confirmation button at the top right of the dialog.
- For a new schedule: look for
button "確認する" (Confirm)
- When updating an existing schedule: look for
button "更新" (Update)
curl -s -X POST http://127.0.0.1:3333/act \
-H 'Content-Type: application/json' \
-d '{"ref":"<confirm_or_update_button_ref>","action":"click"}'
Critical: If this button is not clicked, the date/time changes will not be applied. Always use /snapshot to find the correct ref before clicking.
7. Submit the scheduled post
After the dialog closes and the home screen returns, click button "予約設定" (Schedule settings) to finalize the scheduled post.
curl -s -X POST http://127.0.0.1:3333/act \
-H 'Content-Type: application/json' \
-d '{"ref":"<schedule_submit_ref>","action":"click"}'
8. Verify the scheduled post
Confirm the post appears in the scheduled posts list:
- Click
link "ポストする" (Post) in the side menu
- Click
button "下書き" (Drafts)
- Click
tab "予約済み" (Scheduled)
- Use
/snapshot to verify the post text and scheduled date/time are correct
curl -s -X POST http://127.0.0.1:3333/act \
-H 'Content-Type: application/json' \
-d '{"ref":"<post_button_ref>","action":"click"}'
curl -s -X POST http://127.0.0.1:3333/act \
-H 'Content-Type: application/json' \
-d '{"ref":"<draft_button_ref>","action":"click"}'
curl -s -X POST http://127.0.0.1:3333/act \
-H 'Content-Type: application/json' \
-d '{"ref":"<scheduled_tab_ref>","action":"click"}'
curl -s http://127.0.0.1:3333/snapshot
If the post text and scheduled time match, report success to the user.
9. Close the dialog and return to home
After verification, close the dialog to return to the home screen.
- Click
button "戻る" (Back) or button "閉じる" (Close) as needed
- Repeat until all dialogs are closed
10. Stop the server (if requested by the user)
kill $(lsof -ti:3333) 2>/dev/null
kill $(lsof -ti:9222) 2>/dev/null
Important notes
- Do not ask which profile to use unless the user explicitly needs a non-
default profile
- Add
sleep 1-2 between operations to wait for page loads
- Always use
/snapshot before each action to get fresh refs (refs change when the page navigates or dialogs open/close)
- X's UI is dynamic; use both snapshots and screenshots to identify the correct elements
- After setting the date/time, always click the "確認する" (Confirm) or "更新" (Update) button to apply the changes
- Before final submission, verify the composer DOM text still matches the intended scheduled text
- If
/act type appears to work visually but [data-testid="tweetTextarea_0"] does not match, stop and switch to the CDP keyboard path instead of scheduling