- Rust 100%
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.

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;
enteropens the word breakdown for one post - words — the words you reach for most, next to your longest and shortest posts

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:



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.