From 635b6298e33b02fc0ad2a284c9d3576114513412 Mon Sep 17 00:00:00 2001 From: Santiago Medina Rolong Date: Thu, 19 Feb 2026 20:14:06 -0800 Subject: [PATCH] skills: add xurl skill --- skills/xurl/SKILL.md | 423 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 423 insertions(+) create mode 100644 skills/xurl/SKILL.md diff --git a/skills/xurl/SKILL.md b/skills/xurl/SKILL.md new file mode 100644 index 00000000000..82f955da943 --- /dev/null +++ b/skills/xurl/SKILL.md @@ -0,0 +1,423 @@ +--- +name: xurl +description: A curl-like CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint. Supports multiple apps, OAuth 2.0, OAuth 1.0a, and app-only auth. +--- + +# xurl — Agent Skill Reference + +`xurl` is a CLI tool for the X API. It supports both **shortcut commands** (human/agent‑friendly one‑liners) and **raw curl‑style** access to any v2 endpoint. All commands return JSON to stdout. + +--- + +## Installation + +### Homebrew (macOS) +```bash +brew install --cask xdevplatform/tap/xurl +``` + +### npm +```bash +npm install -g @xdevplatform/xurl +``` + +### Shell script +```bash +curl -fsSL https://raw.githubusercontent.com/xdevplatform/xurl/main/install.sh | bash +``` +Installs to `~/.local/bin`. If it's not in your PATH, the script will tell you what to add. + +### Go +```bash +go install github.com/xdevplatform/xurl@latest +``` + +--- + +## Prerequisites + +Before using any command you must be authenticated. Run `xurl auth status` to check. + +### Register an app (recommended) + +```bash +# Register your X API app credentials (stored in ~/.xurl) +xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET + +# Then authenticate +xurl auth oauth2 +``` + +You can register multiple apps and switch between them: +```bash +xurl auth apps add prod-app --client-id PROD_ID --client-secret PROD_SECRET +xurl auth apps add dev-app --client-id DEV_ID --client-secret DEV_SECRET +xurl auth default prod-app # set default app +xurl auth default prod-app alice # set default app + user +xurl --app dev-app /2/users/me # one-off override +``` + +### Other auth methods + +```bash +# OAuth 1.0a +xurl auth oauth1 \ + --consumer-key KEY --consumer-secret SECRET \ + --access-token TOKEN --token-secret SECRET + +# App‑only bearer token +xurl auth app --bearer-token TOKEN +``` + +Tokens are persisted to `~/.xurl` in YAML format. Each app has its own isolated tokens. Once authenticated, every command below will auto‑attach the right `Authorization` header. + +--- + +## Quick Reference + +| Action | Command | +|---|---| +| Post | `xurl post "Hello world!"` | +| Reply | `xurl reply POST_ID "Nice post!"` | +| Quote | `xurl quote POST_ID "My take"` | +| Delete a post | `xurl delete POST_ID` | +| Read a post | `xurl read POST_ID` | +| Search posts | `xurl search "QUERY" -n 10` | +| Who am I | `xurl whoami` | +| Look up a user | `xurl user @handle` | +| Home timeline | `xurl timeline -n 20` | +| Mentions | `xurl mentions -n 10` | +| Like | `xurl like POST_ID` | +| Unlike | `xurl unlike POST_ID` | +| Repost | `xurl repost POST_ID` | +| Undo repost | `xurl unrepost POST_ID` | +| Bookmark | `xurl bookmark POST_ID` | +| Remove bookmark | `xurl unbookmark POST_ID` | +| List bookmarks | `xurl bookmarks -n 10` | +| List likes | `xurl likes -n 10` | +| Follow | `xurl follow @handle` | +| Unfollow | `xurl unfollow @handle` | +| List following | `xurl following -n 20` | +| List followers | `xurl followers -n 20` | +| Block | `xurl block @handle` | +| Unblock | `xurl unblock @handle` | +| Mute | `xurl mute @handle` | +| Unmute | `xurl unmute @handle` | +| Send DM | `xurl dm @handle "message"` | +| List DMs | `xurl dms -n 10` | +| Upload media | `xurl media upload path/to/file.mp4` | +| Media status | `xurl media status MEDIA_ID` | +| **App Management** | | +| Register app | `xurl auth apps add NAME --client-id ID --client-secret SEC` | +| List apps | `xurl auth apps list` | +| Update app creds | `xurl auth apps update NAME --client-id ID` | +| Remove app | `xurl auth apps remove NAME` | +| Set default (interactive) | `xurl auth default` | +| Set default (command) | `xurl auth default APP_NAME [USERNAME]` | +| Use app per-request | `xurl --app NAME /2/users/me` | +| Auth status | `xurl auth status` | + +> **Post IDs vs URLs:** Anywhere `POST_ID` appears above you can also paste a full post URL (e.g. `https://x.com/user/status/1234567890`) — xurl extracts the ID automatically. + +> **Usernames:** Leading `@` is optional. `@elonmusk` and `elonmusk` both work. + +--- + +## Command Details + +### Posting + +```bash +# Simple post +xurl post "Hello world!" + +# Post with media (upload first, then attach) +xurl media upload photo.jpg # → note the media_id from response +xurl post "Check this out" --media-id MEDIA_ID + +# Multiple media +xurl post "Thread pics" --media-id 111 --media-id 222 + +# Reply to a post (by ID or URL) +xurl reply 1234567890 "Great point!" +xurl reply https://x.com/user/status/1234567890 "Agreed!" + +# Reply with media +xurl reply 1234567890 "Look at this" --media-id MEDIA_ID + +# Quote a post +xurl quote 1234567890 "Adding my thoughts" + +# Delete your own post +xurl delete 1234567890 +``` + +### Reading + +```bash +# Read a single post (returns author, text, metrics, entities) +xurl read 1234567890 +xurl read https://x.com/user/status/1234567890 + +# Search recent posts (default 10 results) +xurl search "golang" +xurl search "from:elonmusk" -n 20 +xurl search "#buildinpublic lang:en" -n 15 +``` + +### User Info + +```bash +# Your own profile +xurl whoami + +# Look up any user +xurl user elonmusk +xurl user @XDevelopers +``` + +### Timelines & Mentions + +```bash +# Home timeline (reverse chronological) +xurl timeline +xurl timeline -n 25 + +# Your mentions +xurl mentions +xurl mentions -n 20 +``` + +### Engagement + +```bash +# Like / unlike +xurl like 1234567890 +xurl unlike 1234567890 + +# Repost / undo +xurl repost 1234567890 +xurl unrepost 1234567890 + +# Bookmark / remove +xurl bookmark 1234567890 +xurl unbookmark 1234567890 + +# List your bookmarks / likes +xurl bookmarks -n 20 +xurl likes -n 20 +``` + +### Social Graph + +```bash +# Follow / unfollow +xurl follow @XDevelopers +xurl unfollow @XDevelopers + +# List who you follow / your followers +xurl following -n 50 +xurl followers -n 50 + +# List another user's following/followers +xurl following --of elonmusk -n 20 +xurl followers --of elonmusk -n 20 + +# Block / unblock +xurl block @spammer +xurl unblock @spammer + +# Mute / unmute +xurl mute @annoying +xurl unmute @annoying +``` + +### Direct Messages + +```bash +# Send a DM +xurl dm @someuser "Hey, saw your post!" + +# List recent DM events +xurl dms +xurl dms -n 25 +``` + +### Media Upload + +```bash +# Upload a file (auto‑detects type for images/videos) +xurl media upload photo.jpg +xurl media upload video.mp4 + +# Specify type and category explicitly +xurl media upload --media-type image/jpeg --category tweet_image photo.jpg + +# Check processing status (videos need server‑side processing) +xurl media status MEDIA_ID +xurl media status --wait MEDIA_ID # poll until done + +# Full workflow: upload then post +xurl media upload meme.png # response includes media id +xurl post "lol" --media-id MEDIA_ID +``` + +--- + +## Global Flags + +These flags work on every command: + +| Flag | Short | Description | +|---|---|---| +| `--app` | | Use a specific registered app for this request (overrides default) | +| `--auth` | | Force auth type: `oauth1`, `oauth2`, or `app` | +| `--username` | `-u` | Which OAuth2 account to use (if you have multiple) | +| `--verbose` | `-v` | Print full request/response headers | +| `--trace` | `-t` | Add `X-B3-Flags: 1` trace header | + +--- + +## Raw API Access + +The shortcut commands cover the most common operations. For anything else, use xurl's raw curl‑style mode — it works with **any** X API v2 endpoint: + +```bash +# GET request (default) +xurl /2/users/me + +# POST with JSON body +xurl -X POST /2/tweets -d '{"text":"Hello world!"}' + +# PUT, PATCH, DELETE +xurl -X DELETE /2/tweets/1234567890 + +# Custom headers +xurl -H "Content-Type: application/json" /2/some/endpoint + +# Force streaming mode +xurl -s /2/tweets/search/stream + +# Full URLs also work +xurl https://api.x.com/2/users/me +``` + +--- + +## Streaming + +Streaming endpoints are auto‑detected. Known streaming endpoints include: +- `/2/tweets/search/stream` +- `/2/tweets/sample/stream` +- `/2/tweets/sample10/stream` + +You can force streaming on any endpoint with `-s`: +```bash +xurl -s /2/some/endpoint +``` + +--- + +## Output Format + +All commands return **JSON** to stdout, pretty‑printed with syntax highlighting. The output structure matches the X API v2 response format. A typical response looks like: + +```json +{ + "data": { + "id": "1234567890", + "text": "Hello world!" + } +} +``` + +Errors are also returned as JSON: +```json +{ + "errors": [ + { + "message": "Not authorized", + "code": 403 + } + ] +} +``` + +--- + +## Common Workflows + +### Post with an image +```bash +# 1. Upload the image +xurl media upload photo.jpg +# 2. Copy the media_id from the response, then post +xurl post "Check out this photo!" --media-id MEDIA_ID +``` + +### Reply to a conversation +```bash +# 1. Read the post to understand context +xurl read https://x.com/user/status/1234567890 +# 2. Reply +xurl reply 1234567890 "Here are my thoughts..." +``` + +### Search and engage +```bash +# 1. Search for relevant posts +xurl search "topic of interest" -n 10 +# 2. Like an interesting one +xurl like POST_ID_FROM_RESULTS +# 3. Reply to it +xurl reply POST_ID_FROM_RESULTS "Great point!" +``` + +### Check your activity +```bash +# See who you are +xurl whoami +# Check your mentions +xurl mentions -n 20 +# Check your timeline +xurl timeline -n 20 +``` + +### Set up multiple apps +```bash +# Register two apps +xurl auth apps add prod --client-id PROD_ID --client-secret PROD_SECRET +xurl auth apps add staging --client-id STG_ID --client-secret STG_SECRET + +# Authenticate users on each +xurl auth default prod +xurl auth oauth2 # authenticates on prod app + +xurl auth default staging +xurl auth oauth2 # authenticates on staging app + +# Switch between them +xurl auth default prod alice # prod app, alice user +xurl --app staging /2/users/me # one-off request against staging +``` + +--- + +## Error Handling + +- Non‑zero exit code on any error. +- API errors are printed as JSON to stdout (so you can still parse them). +- Auth errors suggest re‑running `xurl auth oauth2` or checking your tokens. +- If a command requires your user ID (like, repost, bookmark, follow, etc.), xurl will automatically fetch it via `/2/users/me`. If that fails, you'll see an auth error. + +--- + +## Notes + +- **Rate limits:** The X API enforces rate limits per endpoint. If you get a 429 error, wait and retry. Write endpoints (post, reply, like, repost) have stricter limits than read endpoints. +- **Scopes:** OAuth 2.0 tokens are requested with broad scopes. If you get a 403 on a specific action, your token may lack the required scope — re‑run `xurl auth oauth2` to get a fresh token. +- **Token refresh:** OAuth 2.0 tokens auto‑refresh when expired. No manual intervention needed. +- **Multiple apps:** Register multiple apps with `xurl auth apps add`. Each app has its own isolated credentials and tokens. Switch with `xurl auth default` or `--app`. +- **Multiple accounts:** You can authenticate multiple OAuth 2.0 accounts per app and switch between them with `--username` / `-u` or set a default with `xurl auth default APP USER`. +- **Default user:** When no `-u` flag is given, xurl uses the default user for the active app (set via `xurl auth default`). If no default user is set, it uses the first available token. +- **Token storage:** `~/.xurl` is YAML. Each app stores its own credentials and tokens.