Skip to content

Commit 0db616b

Browse files
ralyodioclaude
andcommitted
Add gh-pulse, the daily GitHub movement + traffic email
Every repo the gh token can see (own + every org, forks excluded) is checked for movement since the previous run: stars, forks, commits, PRs, issues, releases, and the /graphs/traffic numbers (views, unique visitors, clones, referrers, popular content). Movers are ranked by a weighted score and emailed through Resend with 14-day charts (SVG rendered to PNG with @resvg/resvg-js, inline via cid), and new/lost followers are named. GitHub publishes traffic in UTC-day buckets one to two days late, so the window is the growth of each bucket since the previous snapshot rather than a clock: nothing is missed or double counted when a run is skipped. Every run writes a gzipped snapshot of the raw counts and buckets to ~/.local/share/gh-pulse/snapshots; GitHub keeps nothing past 14 days, so those files are the long-run history. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011gfb1vcQH5rf82HfbJvf1Z
1 parent 9564613 commit 0db616b

5 files changed

Lines changed: 906 additions & 0 deletions

File tree

‎README.md‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,44 @@ gh-issues --orgs profullstack --csv=/tmp/issues.csv
128128
Bare `--csv` takes no argument on purpose, so `--csv --limit 10` cannot swallow
129129
the next flag as a filename.
130130

131+
### `gh-pulse`
132+
133+
The daily "what moved on GitHub" email, with charts. Every repo the `gh` token
134+
can see (yours plus every org you belong to, forks excluded) is checked for
135+
movement since the previous run: stars, forks, commits, pull requests, issues,
136+
releases, and the traffic GitHub shows at `/graphs/traffic` (views, unique
137+
visitors, clones, referrers, popular content). Repos with movement are ranked
138+
by a weighted score; each one comes with its traffic, the top ones with a
139+
14-day chart, and new or lost followers are named.
140+
141+
```sh
142+
gh-pulse # scan, email, snapshot
143+
gh-pulse --dry-run # scan and write the HTML, send nothing
144+
gh-pulse --top 12 # how many ranked repos get a chart and detail
145+
gh-pulse --repo profullstack/nixamp # only this repo (repeatable)
146+
```
147+
148+
Movement is measured against the previous snapshot rather than a clock,
149+
because GitHub publishes traffic in UTC-day buckets one to two days late:
150+
each run counts the growth of the 14-day buckets since the last run, so a
151+
skipped day is neither lost nor double counted (the header says how long the
152+
window was). Every run writes `~/.local/share/gh-pulse/snapshots/<date>.json.gz`
153+
with the raw per-repo counts and traffic buckets; GitHub keeps nothing past 14
154+
days, so those files are the long-run history. `out/latest.html`, `.txt` and
155+
`.json` next to them are the last report.
156+
157+
Mail goes through Resend: `RESEND_API_KEY` from the environment, or from
158+
`~/.config/logicsrc/shell.env` when unset (the cron case). The from address
159+
must sit on a verified Resend domain; `GH_PULSE_FROM` overrides it and
160+
`GH_PULSE_TO` (or `--to`) the recipient. The chart rasteriser is a small npm
161+
dependency in `lib/gh-pulse/`, installed on first run.
162+
163+
A daily cron entry looks like:
164+
165+
```
166+
5 13 * * * /home/anthony/scripts/bin/gh-pulse >>/home/anthony/.local/share/gh-pulse/cron.log 2>&1
167+
```
168+
131169
### `gh-prs-merge`
132170

133171
Walks the same scopes and squash-merges every PR that qualifies, oldest first.
@@ -315,6 +353,7 @@ an installer is unavailable and you need the old contents back.
315353

316354
`gh` (authenticated), `jq`, and `awk`. `provision-ssh-keys` needs only OpenSSH
317355
(`ssh`, `ssh-keyscan`, `ssh-keygen`) locally and `bash` on the remote host.
356+
`gh-pulse` wants `node` 20+ and `npm` (once, for its chart dependency).
318357
`domainjson` additionally wants `node`,
319358
`dig`, and the OpenRDAP CLI (`go install github.com/openrdap/rdap/cmd/rdap@latest`,
320359
run from `~/go/bin/rdap` or on `PATH`). `ssh-logins` needs `journalctl` and

0 commit comments

Comments
 (0)