Skip to content

responsiblparty/twitterverse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

twitterverse

Orbital SVG of your X posting scene, derived from your local birdclaw archive. No API keys. No secrets. No cloud. Just a picture of who orbits whom in your reply-graph.

preview

The visualization answers three questions at a glance:

  • Who are my closest posting-friends over the last year, by reply volume?
  • Are we heating or cooling — how does my last-6-months pace compare to the steady-half of 12 months?
  • Who's really in this scene — which second-layer accounts do MULTIPLE of my top-N reply to (the "shared moots" that are the connective tissue)?

Requirements

You need a birdclaw sqlite archive with authored + likes + timeline sync. Or, try it with --demo first (no DB needed).

Install

pip install twitterverse

Or from source:

git clone https://github.com/responsiblparty/twitterverse
cd twitterverse
pip install -e .

Quickstart

Demo — no DB required:

twitterverse render --demo --output demo.html
open demo.html

Against your own birdclaw DB:

twitterverse render \
  --db ~/.birdclaw/birdclaw.sqlite \
  --handle yourhandle \
  --output my-twitterverse.html

With your own profile picture in the sun (birdclaw doesn't sync your own pfp — grab the URL from x.com/<yourhandle> and pass it):

twitterverse render \
  --db ~/.birdclaw/birdclaw.sqlite \
  --handle yourhandle \
  --me-pfp 'https://pbs.twimg.com/profile_images/.../..._400x400.jpg' \
  --output my-twitterverse.html

Configuration

Everything is CLI-flag-tunable, or drop a YAML config file:

twitterverse render --config example.yml --db ~/.birdclaw/birdclaw.sqlite --handle you

See example.yml for all options. The interesting knobs:

flag default what
--n-friends 10 how many friends form the planetary ring (5–20 works well)
--months 12 window for the 12-month reply-edge total
--months-recent 6 window for the trend calculation (heat/cool)
--sun-color #5cd66f the "you" tint. Try #ff9dd8 for pink, #4dc7ff for cool blue
--me-pfp your own profile image URL

How it works

Reply-edge extraction. For each direction:

  • Others → you uses tweets.reply_to_id → tweets.id — reliable, because your own tweets are always in the archive.
  • You → others does NOT use that JOIN — parent tweets you replied to often aren't in your archive, so the JOIN drops most of your outgoing signal into an @unknown bucket. Instead, it parses the leading @handle from your reply text (X convention: reply tweets literally start with @handle1 [@handle2 ...] rest), which recovers ~95%+ of outgoing edges.

If you're building on birdclaw for any social-graph project, that trick is the load-bearing insight.

Trend classification compares your 6-month reply-pace to what would be steady (half of the 12-month total):

  • fire 🔥 — 6mo ≥ 130% of steady-half
  • up ↑ — 110–130%
  • steady → — 90–110%
  • cool ↓ — 60–90%
  • freeze ❄ — < 60%

Satellites are handles that at least 2 of your top-N friends reply to — they're the shared moots that make your scene coherent. Dashed lines connect a satellite to its non-primary friends.

Friend-edges (the amber curves) are direct reply-edges within the top-N. Most people's scenes have 2-4 real internal pairs — a sparse graph, meaning YOU are the bridging hub, not a member of one dense clique.

Modes

twitterverse render --demo                # synthetic data preview
twitterverse render --db … --handle …     # full HTML page (default)
twitterverse derive --db … --handle …     # dump the derive() dict as JSON

Use twitterverse derive if you want to run your own analytics on top of the reply-graph without doing the SQL yourself.

Programmatic use

from twitterverse import derive, render, config

data = derive.derive("~/.birdclaw/birdclaw.sqlite", "yourhandle", n_friends=15)

# Custom render config
cfg = config.load(sun_color="#ff9dd8", me_pfp="https://…", page_title="my scene")

# Full standalone HTML page
html = render.render_page(data, cfg)

# Or just the SVG (embed anywhere)
svg = render.render_svg(data, cfg)

Known imperfections in v0.1

  • Satellite label collisions — when 2 satellites share a primary friend, or when a satellite's label sits close to a planet label, they overlap. No collision-detection yet.
  • Own profile picture not synced. Birdclaw doesn't include your own pfp (you don't appear in your own profile snapshots), so --me-pfp is required if you want your face in the sun. Falls back to the plain green disc otherwise.
  • DiceBear placeholder avatars for accounts that aren't in your profiles table yet. They're deterministic per-handle so they're stable across renders.

License

MIT. Do whatever, don't sue me if birdclaw's schema changes and this breaks.

Related

  • birdclaw — the local-first X archive this depends on.

About

Orbital SVG of your X posting scene, derived from your local birdclaw archive. No API keys.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages