npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

clawuth

v0.1.1

Published

X/Twitter client using browser session tokens — multi-account CLI + Spaces host/listener

Readme

clawuth

A lightweight X/Twitter client that uses your real browser session tokens to call X's internal GraphQL API. No scraping, no Playwright, no official API keys — just direct HTTP calls.

clawuth tweet "Hello from clawuth!"

What It Is

clawuth makes it easy to interact with X programmatically using the same requests your browser makes. You extract two cookie values from your browser (takes 30 seconds), and clawuth handles all the auth headers, GraphQL wiring, and response parsing.

No dependencies. Node 18+ built-ins only: fetch, fs, path, readline.


60-Second Quickstart

1. Install

git clone https://github.com/yourname/clawuth
cd clawuth
npm link        # makes the `clawuth` command available globally

2. Run setup

clawuth setup

The wizard will:

  1. Tell you to open x.com in your browser
  2. Show you a DevTools snippet to copy your session tokens
  3. Ask for an account name and the pasted JSON
  4. Save everything to ~/.clawuth/accounts.json

3. Tweet!

clawuth tweet "Hello from clawuth! 🚀"

CLI Reference

clawuth <command> [args]

| Command | Description | |---|---| | setup | Interactive account setup wizard | | accounts list | List all configured accounts | | accounts add <name> | Add a new account by name | | accounts default <name> | Set the default account | | tweet <text> | Post a tweet | | tweet <text> --reply <id> | Reply to a tweet | | like <tweetId> | Like a tweet | | timeline | Show your home timeline (last 10 tweets) | | search <query> | Search for tweets | | whoami | Show the current account info |


Programmatic API Reference

Setup

import { ClawuthClient } from 'clawuth';

const client = new ClawuthClient();           // uses default account
const client = new ClawuthClient('myacct');   // uses named account

Tweets

// Post a tweet
const tweet = await client.tweet('Hello world!');

// Reply to a tweet
await client.reply('1234567890', 'Great point!');

// Post with options
await client.tweet('Check this out!', {
  replyToId: '1234567890',     // reply to this tweet
  quoteUrl: 'https://x.com/user/status/123',  // quote tweet URL
  mediaIds: ['media_id_1'],    // pre-uploaded media IDs
});

// Delete a tweet
await client.deleteTweet('1234567890');

// Get a single tweet
const tweet = await client.getTweet('1234567890');

Interactions

await client.like('1234567890');
await client.unlike('1234567890');
await client.retweet('1234567890');
await client.unretweet('1234567890');

Timeline

// Home timeline (last 20 tweets)
const { tweets, nextCursor } = await client.timeline({ count: 20 });

// Load more using cursor
const { tweets: more } = await client.timeline({ count: 20, cursor: nextCursor });

// Notifications / mentions
const data = await client.notifications({ count: 20 });
const data = await client.mentions({ count: 20 });

Search

const { tweets, nextCursor } = await client.search('AI agents', {
  count: 20,
  filter: 'Latest',   // 'Latest' | 'Top' | 'People' | 'Photos' | 'Videos'
});

Users

// By screen name (with or without @)
const user = await client.getUser('@myaccount');
const user = await client.getUser('myaccount');

// By numeric ID
const user = await client.getUser('12345678');

// Follow / unfollow
await client.follow('12345678');
await client.unfollow('12345678');

Auth helpers

import { addAccount, listAccounts, setDefault } from 'clawuth';

addAccount('myacct', authToken, ct0, 'myusername');
setDefault('myacct');
const accounts = listAccounts();

Multiple Accounts

You can configure as many accounts as you like:

clawuth accounts add personal
clawuth accounts add work
clawuth accounts list
clawuth accounts default work

Or programmatically:

import { addAccount } from 'clawuth';

addAccount('personal', 'auth_token_1', 'ct0_1', 'myhandle');
addAccount('work', 'auth_token_2', 'ct0_2', 'workhandle');

const client = new ClawuthClient('work');

All accounts are stored in ~/.clawuth/accounts.json.


Token Extraction

Run clawuth setup and follow the prompts — it shows you exactly what to paste in DevTools.

For manual extraction, see scripts/extract-tokens.js for detailed instructions, including the manual cookie extraction method.

⚠️ Token Expiry

Tokens expire when you log out of x.com. If you see a 401 Auth error, your tokens have expired. Re-run clawuth setup (or clawuth accounts add <name>) to refresh them.

To avoid expiry: stay logged in to x.com in your browser. Tokens are session-based and tied to your browser login.


Config File

~/.clawuth/accounts.json looks like:

{
  "__default": "myaccount",
  "myaccount": {
    "name": "myaccount",
    "username": "myaccount",
    "authToken": "...",
    "ct0": "...",
    "addedAt": "2024-01-01T00:00:00.000Z"
  }
}

OpenClaw Channel Plugin

clawuth ships a companion OpenClaw channel plugin that makes X a proper two-way messaging channel — @mentions and DMs arrive in any OpenClaw surface (Telegram, webchat, etc.), and replies post back to X automatically.

Install

Copy (or symlink) the plugin into your OpenClaw extensions directory:

cp -r plugins/openclaw-x ~/.openclaw/extensions/x

Or point OpenClaw at it via plugins.load.paths in your config.

Configure

Add to your OpenClaw config (~/.openclaw/config.json5):

{
  channels: {
    x: {
      enabled: true,
      accounts: {
        default: {
          authToken: "your_auth_token",   // from DevTools → Application → Cookies → https://x.com
          ct0: "your_ct0",               // same place
          username: "yourusername",       // without @
          watchMentions: true,
          watchDMs: true,
          pollIntervalMs: 60000           // check every 60s
        }
      }
    }
  }
}

Activate

openclaw gateway restart

X is now a channel. @mentions and DMs flow in; replies flow out.


X Spaces

Hosting a Space (AI host with voice)

clawuth can host a live X Space with AI-generated speech. Two TTS backends are supported:

Option A — Local Voice Lab (recommended, offline)

Runs on your machine using Kokoro TTS. No API key needed.

# Start the Voice Lab server (one-time setup)
cd ~/voice-lab && python server.py

# Start a Space
clawuth space start "AI and the Future of Open Source"

Available voices: af_nicole (default), af_sarah, af_bella, bm_george, bm_lewis, and more.

VOICE_LAB_VOICE=af_sarah clawuth space start "My Topic"

Option B — ElevenLabs (cloud, works anywhere)

export ELEVENLABS_API_KEY=your_key_here

clawuth space start "My Topic"

Available voices: Sarah (default), Liam, Charlotte, Brian, Jessica.

ELEVENLABS_VOICE_ID=TX3LPaxmHKxFdv7VOQHJ clawuth space start "My Topic"

Backend selection

clawuth auto-detects which backend to use:

  1. Voice Lab — if server is running at localhost:8002
  2. ElevenLabs — if ELEVENLABS_API_KEY is set
  3. Error if neither is available

Force a specific backend:

TTS_BACKEND=elevenlabs clawuth space start "My Topic"
TTS_BACKEND=voicelab   clawuth space start "My Topic"

Also requires FFmpeg: brew install ffmpeg


Listening to a Space (keyword alerts)

Monitor any public Space for keywords. Transcribes live audio using Deepgram.

clawuth space listen https://x.com/i/spaces/XXXXX \
  --keywords "openclaw,vibeclaw,agent" \
  --transcript \
  --alert

Options:

  • --keywords "a,b,c" — comma-separated keywords to watch for
  • --transcript — print live transcript to stdout
  • --alert — send OpenClaw notification on keyword match (default: on)
  • --webhook <url> — POST to URL on keyword match
  • --anon — join as anonymous listener (no account needed)
  • --account <name> — use a specific account
# Show Space info without joining
clawuth space info https://x.com/i/spaces/XXXXX

Requirements

  • Node.js 22+ (built-in fetch + WebSocket)
  • An active x.com account
  • FFmpeg (for Spaces): brew install ffmpeg
  • For TTS: Voice Lab (local) OR ELEVENLABS_API_KEY (cloud)
  • For transcription: Deepgram API key (DEEPGRAM_API_KEY)
  • No npm dependencies

License

MIT