docs: rewrite readme and changelog
This commit is contained in:
+13
-9
@@ -1,13 +1,17 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## Unreleased
|
## 0.1.0 — 2025-12-20
|
||||||
|
|
||||||
## 0.1.0 — 2025-12-05
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Core command set: `tweet`, `reply`, `read`, `replies`, `thread`, `search`, `mentions`, and `whoami`.
|
- CLI commands: `tweet`, `reply`, `read`, `replies`, `thread`, `search`, `mentions`, `whoami`, `check`.
|
||||||
- Dual transports: GraphQL (cookie-based) and Sweetistics (API key); `auto` engine switches to Sweetistics when a key is present.
|
- URL/ID shorthand for `read`, plus `--json` output where supported.
|
||||||
- Sweetistics features: media uploads (images or single video), 15s request timeouts, and conversation fetch with `force=true` so threads/replies are always fresh.
|
- GraphQL engine with cookie auth from Firefox/Chrome/env/flags (macOS browsers).
|
||||||
- Browser credential sourcing: Firefox (`--firefox-profile`) and Chrome (`--chrome-profile`) alongside env/CLI; JSON5 configs (`~/.config/bird/config.json5`, `./.birdrc.json5`) with `allowChrome`/`allowFirefox` toggles and engine defaults.
|
- Sweetistics engine (API key) with automatic fallback when configured.
|
||||||
- `whoami` works with both transports and prefers Sweetistics when available; colorized help banner plus example block.
|
- Media uploads via Sweetistics with per-item alt text (images or single video).
|
||||||
- CI coverage: push/PR workflow (Node 22, pnpm 10, Go stable) running `pnpm test`; test suite expanded (≥70% coverage).
|
- Long-form Notes and Articles extraction for full text output.
|
||||||
|
- Thread + reply fetching with full conversation parsing.
|
||||||
|
- Search + mentions via GraphQL (latest timeline).
|
||||||
|
- JSON5 config files (`~/.config/bird/config.json5`, `./.birdrc.json5`) with engine defaults, profiles, allowChrome/allowFirefox, and timeoutMs.
|
||||||
|
- Request timeouts (`--timeout`, `timeoutMs`) for GraphQL and Sweetistics calls.
|
||||||
|
- Bun-compiled standalone binary via `pnpm run build`.
|
||||||
|
- Query ID refresh helper: `pnpm run graphql:update`.
|
||||||
|
|||||||
@@ -1,23 +1,40 @@
|
|||||||
# bird 🐦 — fast X CLI for tweeting, replying, and reading
|
# bird 🐦 — fast X CLI for tweeting, replying, and reading
|
||||||
|
|
||||||
`bird` is a fast X CLI for tweeting, replying, and reading — powered by cookies or Sweetistics.
|
`bird` is a fast X CLI for tweeting, replying, and reading. It uses either GraphQL cookies or the Sweetistics API.
|
||||||
|
|
||||||
It keeps setup minimal while supporting common workflows for automation or scripting.
|
## Install
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/Projects/bird
|
npm install -g @steipete/bird
|
||||||
pnpm install
|
# or
|
||||||
pnpm run binary # Creates the 'bird' executable
|
pnpm add -g @steipete/bird
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Quickstart
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Show the logged-in account
|
||||||
|
bird whoami
|
||||||
|
|
||||||
|
# Read a tweet (URL or ID)
|
||||||
|
bird read https://x.com/user/status/1234567890123456789
|
||||||
|
bird 1234567890123456789 --json
|
||||||
|
|
||||||
|
# Thread + replies
|
||||||
|
bird thread https://x.com/user/status/1234567890123456789
|
||||||
|
bird replies 1234567890123456789
|
||||||
|
|
||||||
|
# Search + mentions
|
||||||
|
bird search "from:steipete" -n 5
|
||||||
|
bird mentions -n 5
|
||||||
|
```
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
### Commands at a glance
|
|
||||||
- `bird tweet "<text>"` — post a new tweet.
|
- `bird tweet "<text>"` — post a new tweet.
|
||||||
- `bird reply <tweet-id-or-url> "<text>"` — reply to a tweet using its ID or URL.
|
- `bird reply <tweet-id-or-url> "<text>"` — reply to a tweet using its ID or URL.
|
||||||
- `bird read <tweet-id-or-url> [--json]` — fetch tweet content as text or JSON.
|
- `bird read <tweet-id-or-url> [--json]` — fetch tweet content as text or JSON.
|
||||||
|
- `bird <tweet-id-or-url> [--json]` — shorthand for `read` when only a URL or ID is provided.
|
||||||
- `bird replies <tweet-id-or-url> [--json]` — list replies to a tweet.
|
- `bird replies <tweet-id-or-url> [--json]` — list replies to a tweet.
|
||||||
- `bird thread <tweet-id-or-url> [--json]` — show the full conversation thread.
|
- `bird thread <tweet-id-or-url> [--json]` — show the full conversation thread.
|
||||||
- `bird search "<query>" [-n count] [--json]` — search for tweets matching a query.
|
- `bird search "<query>" [-n count] [--json]` — search for tweets matching a query.
|
||||||
@@ -25,196 +42,82 @@ pnpm run binary # Creates the 'bird' executable
|
|||||||
- `bird whoami` — print which Twitter account your cookies belong to.
|
- `bird whoami` — print which Twitter account your cookies belong to.
|
||||||
- `bird check` — show which credentials are available and where they were sourced from.
|
- `bird check` — show which credentials are available and where they were sourced from.
|
||||||
|
|
||||||
### Examples
|
## Engines
|
||||||
|
|
||||||
```bash
|
- `--engine graphql` (default) — use Twitter/X GraphQL with cookies (Chrome/Firefox/env/flags).
|
||||||
# Show the logged-in account via GraphQL cookies
|
- `--engine sweetistics` — use Sweetistics API key (no browser cookies needed).
|
||||||
bird whoami
|
- `--engine auto` — Sweetistics if a key is available, otherwise GraphQL.
|
||||||
|
|
||||||
# Use Firefox profile cookies instead of Chrome
|
Global options:
|
||||||
bird --firefox-profile default-release whoami
|
- `--timeout <ms>`: abort requests after the given timeout (milliseconds).
|
||||||
|
|
||||||
# Send a tweet
|
## Authentication (GraphQL)
|
||||||
bird tweet "hello from bird"
|
|
||||||
|
|
||||||
# Check replies to a tweet
|
`bird` resolves credentials in this order:
|
||||||
bird replies https://x.com/user/status/1234567890123456789
|
|
||||||
```
|
|
||||||
|
|
||||||
Transport (engine) selection:
|
1. CLI flags: `--auth-token`, `--ct0`
|
||||||
- `--engine graphql|sweetistics|auto` (default `graphql`).
|
2. Environment variables: `AUTH_TOKEN`, `CT0` (fallback: `TWITTER_AUTH_TOKEN`, `TWITTER_CT0`)
|
||||||
- `sweetistics`: use Sweetistics API key, no browser cookies needed.
|
3. Browser cookies (macOS): Firefox or Chrome profiles
|
||||||
- `graphql`: use Twitter/X GraphQL with cookies (Chrome/Firefox/env/flags).
|
|
||||||
- `auto`: Sweetistics if an API key is available, otherwise GraphQL.
|
|
||||||
|
|
||||||
You can set persistent defaults via config files (JSON5):
|
Browser cookie sources:
|
||||||
|
- Firefox (default): `~/Library/Application Support/Firefox/Profiles/<profile>/cookies.sqlite`
|
||||||
|
- Chrome: `~/Library/Application Support/Google/Chrome/<Profile>/Cookies`
|
||||||
|
|
||||||
|
## Config (JSON5)
|
||||||
|
|
||||||
|
Config precedence: CLI flags > env vars > project config > global config.
|
||||||
|
|
||||||
- Global: `~/.config/bird/config.json5`
|
- Global: `~/.config/bird/config.json5`
|
||||||
- Project: `./.birdrc.json5` (overrides global)
|
- Project: `./.birdrc.json5`
|
||||||
|
|
||||||
Example `~/.config/bird/config.json5` (Firefox + GraphQL defaults):
|
Example `~/.config/bird/config.json5`:
|
||||||
|
|
||||||
```json5
|
```json5
|
||||||
{
|
{
|
||||||
engine: "graphql",
|
engine: "graphql",
|
||||||
// Prefer Firefox cookies by default
|
|
||||||
firefoxProfile: "default-release",
|
firefoxProfile: "default-release",
|
||||||
// Optional: Sweetistics defaults if you want fallback/overrides
|
|
||||||
sweetisticsApiKey: "sweet-...",
|
sweetisticsApiKey: "sweet-...",
|
||||||
// Allow/deny cookie sources (both default to true)
|
|
||||||
allowFirefox: true,
|
allowFirefox: true,
|
||||||
// Disable Chrome cookies entirely (optional)
|
allowChrome: false,
|
||||||
allowChrome: false
|
timeoutMs: 20000
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Precedence: CLI flags > environment variables > project config > global config.
|
Environment shortcuts:
|
||||||
|
- `SWEETISTICS_API_KEY`, `SWEETISTICS_BASE_URL`
|
||||||
|
- `BIRD_ENGINE`, `BIRD_TIMEOUT_MS`
|
||||||
|
|
||||||
### Credential sources (macOS)
|
## Output
|
||||||
|
|
||||||
Used only when transport resolves to **graphql**:
|
- `--json` prints raw tweet objects for read/replies/thread/search/mentions.
|
||||||
- **Firefox (default)**: `~/Library/Application Support/Firefox/Profiles/<profile>/cookies.sqlite`. `--firefox-profile <name>` (defaults to `default-release` if present).
|
- `read` returns full text for Notes and Articles when present.
|
||||||
- **Chrome**: `~/Library/Application Support/Google/Chrome/<Profile>/Cookies` (WAL/SHM copied too). `--chrome-profile <name>`.
|
|
||||||
- **Env/flags** always override browser cookies.
|
|
||||||
|
|
||||||
Transport is chosen first; then, if transport is GraphQL, the cookie source is resolved with the same precedence.
|
## Media uploads (Sweetistics only)
|
||||||
|
|
||||||
Config precedence: CLI flags > environment variables > project config (`.birdrc.json5`) > global config (`~/.config/bird/config.json5`).
|
- Attach media with `--media` (repeatable) and optional `--alt` per item.
|
||||||
When `allowChrome` or `allowFirefox` is set to `false`, that source is skipped entirely during credential resolution.
|
- Up to 4 images, or 1 video (no mixing). Supported: jpg, jpeg, png, webp, gif, mp4, mov.
|
||||||
|
|
||||||
### Post a tweet
|
Example:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bird tweet "Hello from bird!"
|
bird --engine sweetistics tweet "hi" --media img.png --alt "desc"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Media uploads (Sweetistics only)
|
|
||||||
- Attach images or a single video with `--media` (repeatable) and optional `--alt` (aligned by order):
|
|
||||||
- `bird --engine sweetistics tweet "hi" --media img.png --alt "desc"`
|
|
||||||
- Up to 4 images, or 1 video (no mixing video+images). Supported: jpg, jpeg, png, webp, gif, mp4, mov.
|
|
||||||
- Media uploads currently require the Sweetistics engine (API key). GraphQL-only mode will reject `--media`.
|
|
||||||
- All Sweetistics calls have a 15s timeout so the CLI won’t hang if the API is slow or unreachable.
|
|
||||||
|
|
||||||
⚠️ GraphQL mode uses X’s internal endpoints and is rate‑limited aggressively; expect 429s if you run many reads/writes without Sweetistics.
|
|
||||||
|
|
||||||
### Reply to a tweet
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Using tweet URL
|
|
||||||
bird reply "https://x.com/user/status/1234567890" "This is my reply"
|
|
||||||
|
|
||||||
# Using tweet ID directly
|
|
||||||
bird reply 1234567890 "This is my reply"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Read a tweet
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Get tweet content by URL or ID
|
|
||||||
bird read "https://x.com/user/status/1234567890"
|
|
||||||
bird read 1234567890 --json
|
|
||||||
```
|
|
||||||
|
|
||||||
### Search tweets
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Search for tweets containing a query
|
|
||||||
bird search "claude AI" -n 10
|
|
||||||
|
|
||||||
# Search for mentions of a user
|
|
||||||
bird search "@clawdbot"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Find mentions
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Shortcut to search for @clawdbot mentions
|
|
||||||
bird mentions -n 10
|
|
||||||
bird mentions --json
|
|
||||||
```
|
|
||||||
|
|
||||||
### Check credentials
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bird check
|
|
||||||
```
|
|
||||||
|
|
||||||
## Authentication
|
|
||||||
|
|
||||||
`bird` resolves credentials in the following order of priority:
|
|
||||||
|
|
||||||
1. **CLI arguments** (highest priority)
|
|
||||||
```bash
|
|
||||||
bird --auth-token "xxx" --ct0 "yyy" tweet "Hello"
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Environment variables**
|
|
||||||
```bash
|
|
||||||
export AUTH_TOKEN="xxx"
|
|
||||||
export CT0="yyy"
|
|
||||||
bird tweet "Hello"
|
|
||||||
```
|
|
||||||
|
|
||||||
Alternative env var names: `TWITTER_AUTH_TOKEN`, `TWITTER_CT0`
|
|
||||||
|
|
||||||
3. **Chrome cookies** (fallback - macOS only)
|
|
||||||
- Automatically extracts from Chrome's cookie database
|
|
||||||
- Requires Chrome to be logged into x.com
|
|
||||||
- May prompt for keychain access on first run
|
|
||||||
|
|
||||||
### Credential sources (macOS)
|
|
||||||
|
|
||||||
Used only when transport resolves to **graphql**:
|
|
||||||
- **Firefox (default)**: `~/Library/Application Support/Firefox/Profiles/<profile>/cookies.sqlite`. `--firefox-profile <name>` (defaults to `default-release` if present).
|
|
||||||
- **Chrome**: `~/Library/Application Support/Google/Chrome/<Profile>/Cookies` (WAL/SHM copied too). `--chrome-profile <name>`.
|
|
||||||
- **Env/flags** always override browser cookies.
|
|
||||||
|
|
||||||
Precedence: CLI flags > env vars > project config > global config. Transport is chosen first; then, if transport is GraphQL, cookie source is chosen.
|
|
||||||
|
|
||||||
### Posting via Sweetistics (API key)
|
|
||||||
|
|
||||||
If you have a Sweetistics API key, `bird` can post through the Sweetistics SaaS instead of using local Twitter cookies:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export SWEETISTICS_API_KEY="sweet-..."
|
|
||||||
bird tweet "Hello from Sweetistics!"
|
|
||||||
|
|
||||||
# Optional: point to a self-hosted instance
|
|
||||||
bird --sweetistics-base-url "http://localhost:3000" --sweetistics-api-key "sweet-..." tweet "hi"
|
|
||||||
```
|
|
||||||
|
|
||||||
When an API key is present, `bird` will use Sweetistics’ `/api/actions/tweet` endpoint and skip local cookie resolution.
|
|
||||||
All Sweetistics calls have a 15s timeout so the CLI won’t hang if the API is slow or unreachable.
|
|
||||||
|
|
||||||
**Threads/replies freshness (Sweetistics):** conversation calls (`thread`, `replies`) are requested with `force=true`, bypassing Sweetistics cache to ensure the latest tweets are returned.
|
|
||||||
|
|
||||||
⚠️ GraphQL mode uses X’s internal endpoints and is rate‑limited aggressively; expect 429s if you run many reads/writes without Sweetistics.
|
|
||||||
|
|
||||||
### Getting Your Cookies
|
|
||||||
|
|
||||||
1. Open Chrome and log into x.com
|
|
||||||
2. Open DevTools (Cmd+Option+I)
|
|
||||||
3. Go to Application > Cookies > x.com
|
|
||||||
4. Copy the values for `auth_token` and `ct0`
|
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Run in development mode
|
cd ~/Projects/bird
|
||||||
|
pnpm install
|
||||||
|
pnpm run build # dist/ + bun binary
|
||||||
|
pnpm run build:dist # dist/ only
|
||||||
|
pnpm run build:binary
|
||||||
|
|
||||||
pnpm run dev tweet "Test"
|
pnpm run dev tweet "Test"
|
||||||
|
|
||||||
# Run tests
|
|
||||||
pnpm test
|
pnpm test
|
||||||
|
|
||||||
# Run linter
|
|
||||||
pnpm run lint
|
pnpm run lint
|
||||||
|
|
||||||
# Fix lint issues
|
|
||||||
pnpm run lint:fix
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- Chrome cookie extraction requires macOS (uses `sqlite3` and `security` CLI tools).
|
- GraphQL uses internal X endpoints and can be rate limited (429).
|
||||||
- The keychain access may block when running over SSH; use environment variables instead.
|
- Query IDs rotate; refresh them with `pnpm run graphql:update`.
|
||||||
- Twitter/X rotates GraphQL query IDs; refresh them with `pnpm run graphql:update` (writes `src/lib/query-ids.json`).
|
|
||||||
|
|||||||
Reference in New Issue
Block a user