mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-07 22:44:16 +00:00
skills: add xurl skill
This commit is contained in:
committed by
Peter Steinberger
parent
283029bdea
commit
635b6298e3
423
skills/xurl/SKILL.md
Normal file
423
skills/xurl/SKILL.md
Normal file
@@ -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.
|
||||
Reference in New Issue
Block a user