
Security News
Feross on TBPN: How North Korea Hijacked Axios
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.
frigatebird
Advanced tools
Playwright-first X CLI with bird-style parity and resilient web automation
frigatebird is a Playwright-first X CLI that preserves the familiar bird command-line experience while running on browser automation instead of private GraphQL internals.
bird set a high bar for fast, scriptable X workflows. After deprecation and de-open-sourcing, teams still needed the same CLI ergonomics without depending on internal API behavior.
frigatebird is the continuity path:
bird-style command surface.Frigatebird automates X’s web UI and relies on selectors/flows that X can change at any time. Expect occasional breakage when X ships UI changes.
npm install
npx playwright install chromium
When published to npm:
npm install -g frigatebird
# Show authenticated account
frigatebird whoami
# Read a tweet (URL or ID)
frigatebird read https://x.com/user/status/1234567890123456789
frigatebird 1234567890123456789 --json
# Post and reply
frigatebird tweet "hello from frigatebird"
frigatebird reply 1234567890123456789 "thanks"
# Publish a long-form article
frigatebird article "Launch notes" "Today we shipped..."
frigatebird article "Draft from file" --body-file ./article.md
# Search and mentions
frigatebird search "from:openai" -n 5
frigatebird mentions -n 5
# Lists and list timeline
frigatebird lists --json
frigatebird list-timeline 1234567890 -n 20
# Follow graph
frigatebird following -n 20 --json
frigatebird followers -n 20 --json
# List membership automation
frigatebird add "AI News" @openai @anthropicai
frigatebird remove @openai "AI News"
frigatebird batch accounts.json
frigatebird tweet "<text>" — post a tweet.frigatebird post "<text>" — alias for tweet.frigatebird article "<title>" [body] [--body-file path] — publish a long-form article.frigatebird reply <tweet-id-or-url> "<text>" — reply to a tweet.frigatebird read <tweet-id-or-url> [--json] [--json-full] — read one tweet.frigatebird <tweet-id-or-url> [--json] — shorthand for read.frigatebird replies <tweet-id-or-url> [--all] [--max-pages n] [--cursor str] [--delay ms] [-n count] [--json] [--json-full] — list replies.frigatebird thread <tweet-id-or-url> [--all] [--max-pages n] [--cursor str] [--delay ms] [-n count] [--json] [--json-full] — show thread/conversation tweets.frigatebird search "<query>" [-n count] [--all] [--max-pages n] [--cursor str] [--delay ms] [--json] [--json-full] — search tweets.frigatebird mentions [--user @handle] [-n count] [--json] [--json-full] — mention timeline/search.frigatebird user-tweets <@handle> [-n count] [--all] [--max-pages n] [--cursor str] [--delay ms] [--json] [--json-full] — profile tweets.frigatebird home [-n count] [--following] [--all] [--max-pages n] [--delay ms] [--json] [--json-full] — home timeline.frigatebird bookmarks [-n count] [--folder-id id] [--all] [--max-pages n] [--cursor str] [--expand-root-only] [--author-chain] [--author-only] [--full-chain-only] [--include-ancestor-branches] [--include-parent] [--thread-meta] [--sort-chronological] [--delay ms] [--json] [--json-full] — bookmarks + optional thread expansion.frigatebird unbookmark <tweet-id-or-url...> [--json] — remove bookmark(s).frigatebird like <tweet-id-or-url> — like a tweet.frigatebird retweet <tweet-id-or-url> — repost a tweet.frigatebird likes [-n count] [--all] [--max-pages n] [--cursor str] [--delay ms] [--json] [--json-full] — liked tweets.frigatebird follow <username-or-id> — follow user.frigatebird unfollow <username-or-id> — unfollow user.frigatebird following [--user userId] [-n count] [--all] [--max-pages n] [--cursor str] [--delay ms] [--json] [--json-full] — accounts a user follows.frigatebird followers [--user userId] [-n count] [--all] [--max-pages n] [--cursor str] [--delay ms] [--json] [--json-full] — accounts following a user.frigatebird lists [--member-of] [-n count] [--json] [--json-full] — list your lists.frigatebird list [--member-of] [-n count] [--json] [--json-full] — alias for lists.frigatebird list-timeline <list-id-or-url> [-n count] [--all] [--max-pages n] [--cursor str] [--delay ms] [--json] [--json-full] — timeline for a list.frigatebird news [-n count] [--ai-only] [--with-tweets] [--tweets-per-item n] [--for-you] [--news-only] [--sports] [--entertainment] [--trending-only] [--json] [--json-full] — explore/news aggregation.frigatebird trending — alias for news.frigatebird about <@handle> [--json] — profile origin/location metadata.frigatebird query-ids [--fresh] [--json] — compatibility command (Playwright mode does not require GraphQL query IDs).frigatebird whoami [--json] — active authenticated account.frigatebird check — credential/session status.frigatebird refresh [--json] — refresh local auth cookie cache.frigatebird add <listName> <handles...> [--no-headless] [--json] — add handles to list.frigatebird remove <handle> <listName> [--no-headless] [--json] — remove handle from list.frigatebird batch <file.json> [--no-headless] [--json] — batch list updates from JSON.frigatebird help [command] — command help.--auth-token <token>--ct0 <token>--base-url <url> (default https://x.com, useful for fixture/e2e)--cookie-source <chrome|firefox|safari|edge> (repeatable)--chrome-profile <name>--chrome-profile-dir <path>--firefox-profile <name>--cookie-timeout <ms>--timeout <ms>--quote-depth <n>--compat-json (strict bird-style JSON envelopes + field names)--media <path> (repeatable)--alt <text> (repeatable)--plain--no-emoji--no-color--no-headlessMedia rules:
jpg, jpeg, png, webp, gif, mp4, m4v, movFrigatebird uses your existing X web session and cookie credentials. No X API key required.
Resolution order:
--auth-token, --ct0)AUTH_TOKEN, CT0, fallbacks below)@steipete/sweet-cookieWhen --cookie-source is explicitly set and differs from cached auth source metadata, Frigatebird clears cached auth and re-resolves cookies from the requested source order.
If auth fails:
frigatebird refresh
frigatebird check
frigatebird whoami
Precedence: CLI flags > env vars > project config > global config.
Config files:
~/.config/bird/config.json5~/.config/frigatebird/config.json5./.birdrc.json5./.frigatebirdrc.json5Supported keys:
authToken, ct0, baseUrlcookieSourcechromeProfile, chromeProfileDir, firefoxProfilecookieTimeoutMs, timeoutMs, quoteDepthExample:
{
cookieSource: ["chrome", "safari"],
chromeProfile: "Default",
timeoutMs: 20000,
quoteDepth: 1
}
Environment vars:
AUTH_TOKEN, CT0, TWITTER_AUTH_TOKEN, TWITTER_CT0BIRD_COOKIE_SOURCE, FRIGATEBIRD_COOKIE_SOURCEBIRD_BASE_URL, FRIGATEBIRD_BASE_URLBIRD_CHROME_PROFILE, BIRD_CHROME_PROFILE_DIR, BIRD_FIREFOX_PROFILE and FRIGATEBIRD_* variantsBIRD_TIMEOUT_MS, BIRD_COOKIE_TIMEOUT_MS, BIRD_QUOTE_DEPTH and FRIGATEBIRD_* variantsNO_COLOR, BIRD_PLAIN, FRIGATEBIRD_PLAIN--json gives machine-readable output for read/timeline/list commands.--json-full includes raw compatibility payloads where available.--plain disables emoji + color for stable scripts.--compat-json switches JSON output to strict bird-style schemas.nextCursor when additional pages are available; pass it back via --cursor.items and alias keys:
tweetsuserslistsnewsnpm install
npx playwright install chromium
npm run build
npm run lint
npm run test:run # unit/integration
npm run test:coverage # unit/integration + coverage
npm run test:e2e # e2e only
npm run test:e2e:live -- --list-name testlist001 # opt-in live mutation e2e (article mutation disabled by default)
npm run smoke:pack-install
Live mutation e2e requirements:
--list-name <your-list-name>FRIGATEBIRD_AUTH_TOKENFRIGATEBIRD_CT0--cookie-source <source>FRIGATEBIRD_LIVE_COOKIE_SOURCE, FRIGATEBIRD_LIVE_EXPECTED_HANDLE_PREFIX, FRIGATEBIRD_LIVE_TARGET_HANDLE--enable-premium-features-e2e --article-cookie-source chrome --article-expected-handle-prefix Oceanswave.github/workflows/ci.yml.github/workflows/release.yml (triggered by GitHub Release published, trusted publishing/OIDC).github/workflows/live-e2e.yml
workflow_dispatch (list_name, cookie_source, premium_features_e2e, article inputs)FRIGATEBIRD_ENABLE_SCHEDULED_LIVE_E2E=1FRIGATEBIRD_LIVE_E2E_LIST_NAME, FRIGATEBIRD_LIVE_E2E_COOKIE_SOURCE, FRIGATEBIRD_LIVE_E2E_PREMIUM, and optional article/guard prefix vars.github/workflows/auto-merge.yml (uses pull_request_target; enables squash auto-merge for non-draft same-repo PRs)RELEASE.mdquery-ids is intentionally kept for CLI compatibility with historical bird workflows.FAQs
Playwright-first X CLI with bird-style parity and resilient web automation
We found that frigatebird demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.

Security News
OpenSSF has issued a high-severity advisory warning open source developers of an active Slack-based campaign using impersonation to deliver malware.

Research
/Security News
Malicious packages published to npm, PyPI, Go Modules, crates.io, and Packagist impersonate developer tooling to fetch staged malware, steal credentials and wallets, and enable remote access.