A command-line toolkit that collects repository activity from the GitHub Events API, stores it as daily JSONL files, and produces per-contributor statistics for any time window. Reports can be printed to the console or published to a Slack channel as formatted messages.
It is designed for teams that want to track and share contributor activity in a GitHub repository without relying on the GitHub web interface.
The toolkit provides three CLI commands:
github-poll— fetches the latest events from the GitHub REST API, deduplicates them, and appends them to a local JSONL collection (one file per day).github-stats— reads the stored events for a given time window, aggregates per-contributor activity, and prints the results to the console.github-publish— computes the same statistics and posts them to a Slack channel using Block Kit formatted messages.
Typical usage is to schedule github-poll frequently (e.g. every hour via
GitHub Actions) so that no events are lost, then run github-stats or
github-publish on demand or on a schedule to generate reports.
An activity point is counted for each of the following user actions:
- Commit pushed.
- Issue closed (unless marked as Stale).
- Comment added to an Issue or Pull Request.
- Pull Request review (approved or rejected).
- Pull Request merged.
Events are stored as one JSONL file per day (YYYY-MM-DD.jsonl) under
COLLECTION_PATH. A companion metadata file (YYYY-MM-DD-metadata.json)
tracks how many events were fetched, how many were written after
deduplication, and rate-limit status.
github-stats and github-publish operate on a time window defined by
SINCE and UNTIL. If SINCE is omitted, all stored events are used.
If UNTIL is omitted, the current time is used. Daily files older than
30 days are automatically pruned during github-poll.
github-publish performs a publish-time reconciliation against the
GitHub REST API for the requested window. This recovers issue closures
and PR open/merge events that were missed by the Events-API poller
(the Events API only retains the 300 most recent public events). When
the REST API is unavailable the publisher emits a warning; if the
window is also empty in the local collection it exits non-zero rather
than producing an under-reported message.
Per-poll diagnostics are appended to <date>-metadata.json (one
record per poll) so polling gaps can be analyzed after the fact.
Install globally via npm:
npm i -g @adguard/github-statsOr run with npx without installing:
npx @adguard/github-stats <command>-
Set the required environment variables:
export COLLECTION_PATH=./stats-data export REPO=AdguardTeam/AdguardFilters export GITHUB_TOKEN=ghp_xxx
-
Poll today's events:
github-poll
-
Print stats for the last week:
export SINCE=2025-05-01T00:00:00Z export UNTIL=2025-05-08T00:00:00Z github-stats
github-pollRequired variables: COLLECTION_PATH, REPO.
Recommended variable: GITHUB_TOKEN (without it the GitHub API limits
unauthenticated requests to 60 per hour).
Each run fetches the most recent events from the GitHub Events API, removes duplicates already present in today's JSONL file, and appends new ones. The metadata sidecar is updated in place. Re-running on the same day is safe and idempotent.
The YYYY-MM-DD-metadata.json sidecar contains a JSON array of records, one per
poll run. (Legacy files written as a single object are automatically migrated to an array
on the next poll.)
| Field | Description |
|---|---|
timestamp |
ISO 8601 time when this poll ran |
totalEvents |
Events fetched from GitHub API |
eventsInFile |
Unique events written after deduplication |
pagesCollected |
Number of API pages processed |
rateLimitReached |
Whether the API rate limit was hit |
rateLimitRemaining |
Remaining API requests at poll time |
rateLimitReset |
ISO 8601 timestamp when the rate limit resets |
oldestEventAt |
created_at of the oldest event returned by this poll |
newestEventAt |
created_at of the newest event returned by this poll |
gapSuspected |
true if no successful poll for >90 min or event window gap detected |
error |
Error message if the poll failed, otherwise null |
github-statsRequired variables: COLLECTION_PATH, REPO.
Optional variables: SINCE, UNTIL, GITHUB_TOKEN.
Outputs a table of contributors ranked by activity points within the specified time window, plus a repository summary (new issues, closed issues, new and merged pull requests, etc.).
github-publishRequired variables: COLLECTION_PATH, REPO, SLACK_OAUTH_TOKEN,
SLACK_CHANNEL_ID.
Optional variables: SINCE, UNTIL, GITHUB_TOKEN.
Posts the same statistics as github-stats to the configured Slack
channel. Team members are always included; external contributors only
appear if their activity points are at or above the
MIN_REQUIRED_ACTIVITY threshold defined in the source code.
All configuration is provided through environment variables. The CLI
entries load a .env file from the working directory if one exists.
| Variable | Required for | Description |
|---|---|---|
COLLECTION_PATH |
All commands | Directory for daily JSONL files and metadata sidecars. |
REPO |
All commands | Target repository in owner/repo_name form. |
GITHUB_TOKEN |
poll (recommended), stats, publish |
GitHub Personal Access Token. Raises the API rate limit from 60 to 5000 requests per hour. |
SINCE |
stats, publish |
Lower bound of the time window (ISO 8601). All stored events are used if omitted. |
UNTIL |
stats, publish |
Upper bound of the time window (ISO 8601). Defaults to now if omitted. |
RECONCILE |
— | Set to true to back-fill missing events from the GitHub REST API during stats/publish. Disabled by default. |
| Variable | Required for | Description |
|---|---|---|
SLACK_OAUTH_TOKEN |
publish |
Slack bot token (xoxb-...). |
SLACK_CHANNEL_ID |
publish |
Slack channel ID to post messages to. |
Example workflows for polling, printing, and publishing are available in
the examples directory. A typical setup runs github-poll
every hour to avoid losing events (the GitHub Events API returns at most
300 recent events per repository), and runs github-publish once a day
to post a summary.
- Development guide — local setup, build, test, and contribution workflow.
- LLM agent rules — coding conventions, architecture, and project structure.
- Changelog — release history.