rust TUI that lets you track your leaflet writing stats.

README.md

forest #

A little TUI that shows you your own writing on leaflet.pub — and anything else published with the same open standard — read straight off your Personal Data Server. No login, no indexer, nothing in the middle.

the splash screen

What it does #

Give it a handle and it pulls your posts off your PDS, then lays them out three ways:

  • overview — how much you've written and when: posts, words, reading time, a month-by-month activity chart, your publications and your tags
  • posts — every post with its word count and reading time; enter opens the word breakdown for one post
  • words — the words you reach for most, next to your longest and shortest posts

the overview

You probably keep more than one blog. Hit p and pick one — nothing is refetched, the filter is applied to what's already in memory:

the publication picker

the posts view

the words view

Running it #

cargo run                       # asks for a handle
cargo run -- goose.art          # or pass one in
cargo run -- --dump goose.art   # plain text report, no TUI

A handle (alice.bsky.social), a domain (example.com) or a DID (did:plc:…) all work. --help lists the flags.

Keys #

key
1 2 3, tab, ← → overview, posts, words
j k, arrows, pgup pgdn move, or scroll the activity chart
g G jump to the first / last row
enter open a post
s change the sort order (posts view)
p switch publication
r refetch everything from the PDS
? the full key list
q, ctrl-c quit

How it reads your writing #

The handle is resolved through _atproto DNS, /.well-known/atproto-did, or the public app view as a fallback, and the DID document that comes back names your PDS. The posts themselves come from site.standard.document (standard.site) and the older pub.leaflet.document, both read off your own server.

Only prose is counted. Titles, image alt text, button labels, link cards and embeds don't inflate your word count.

The tree #

The evergreen on the splash screen is a plain text file: assets/tree.txt. Edit it, replace it, or empty it to get rid of it. Point FOREST_TREE at another file to swap it out without a rebuild:

FOREST_TREE=~/my-tree.txt cargo run

Development #

cargo test
cargo clippy --all-targets

No config file, no state on disk — it reads your PDS every time you press r.