fork-contributor-leaderboard
This Claude Code skill ranks developers contributing to a GitHub fork ecosystem by activity across commits, upstream pull requests, code reviews, and first-time contributions. Use it weekly to surface contributor recognition signals distinct from social engagement metrics, feeding public acknowledgment back into a community flywheel where code work receives the same visibility as social mentions. It analyzes active forks, upstream PRs, and review activity to answer who is actively moving the project forward.
git clone --depth 1 https://github.com/aaronjmars/aeon /tmp/fork-contributor-leaderboard && cp -r /tmp/fork-contributor-leaderboard/skills/fork-contributor-leaderboard ~/.claude/skills/fork-contributor-leaderboardSKILL.md
<!-- autoresearch: variation A — better inputs (compare API + PR reviews + first-timer signal), folds in B's "Movement This Week" lede -->
> **${var}** — Target repo to scan contributors of (e.g. "owner/aeon"). If empty, reads from memory/watched-repos.md.
Today is ${today}. Rank the humans behind the fork fleet — who's pushing commits into their forks, who's sending work back upstream, who's reviewing other people's code, and who's building new skills that upstream hasn't seen yet.
This complements `skill-leaderboard` (what is popular) and `fork-fleet` (which forks diverge). This skill asks: **who are the people?**
## Why this exists
The `tweet-allocator` skill rewards social mentions with $AEON. Code contributors get nothing — no recognition, no signal that upstream values their work. This leaderboard is the contributor-side mirror: public recognition for the people actively moving the project forward. Run it weekly, name names, and the flywheel closes.
## Steps
1. **Determine the target repo.** If `${var}` is set, use that. Otherwise read `memory/watched-repos.md` and use the first entry. Store as `TARGET_REPO`. Resolve the upstream default branch once: `UPSTREAM_BRANCH=$(gh api repos/${TARGET_REPO} --jq .default_branch)`.
2. **Fetch all active forks** (pushed within the last 30 days):
```bash
CUTOFF=$(date -u -d "30 days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-30d +%Y-%m-%dT%H:%M:%SZ)
gh api repos/${TARGET_REPO}/forks --paginate \
--jq "[.[] | select(.pushed_at > \"$CUTOFF\") | {owner: .owner.login, full_name: .full_name, default_branch, pushed_at, stargazers_count, created_at}]"
```
If no active forks found, log `FORK_CONTRIBUTOR_LEADERBOARD_NO_FORKS` to `memory/logs/${today}.md` and stop (no notification).
3. **Fetch all upstream PRs** in one paginated call. Keep `author_association` so we can flag first-time contributors without an extra call:
```bash
gh api "repos/${TARGET_REPO}/pulls?state=all&per_page=100" --paginate \
--jq '[.[] | {number, state, merged_at, user: .user.login, title, created_at, author_association}]'
```
Build a map `{login -> {opened: N, merged: N, first_time: bool, pr_titles: [...]}}` keyed on `.user.login`. Set `first_time: true` if any of their PRs has `author_association == "FIRST_TIME_CONTRIBUTOR"`.
Skip bots: any login ending in `[bot]`, plus `aaronjmars`, `aeonframework`, `github-actions`.
4. **Fetch all upstream PR review comments** in one paginated call (this is the missing reviewer signal):
```bash
SINCE=$CUTOFF
gh api "repos/${TARGET_REPO}/pulls/comments?since=${SINCE}&per_page=100" --paginate \
--jq '[.[] | {user: .user.login, pr_url: .pull_request_url, created_at}]'
```
Build `{login -> review_comments: N}`. Apply the same bot filter. Cap at 20 review comments per contributor (someone who left 200 nit comments on one PR shouldn't dominate).
5. **For each active fork, get authored commit count via the compare endpoint** (one call per fork, returns `ahead_by` plus a commits array with author metadata — replaces the prior per-fork pagination loop):
```bash
gh api "repos/${TARGET_REPO}/compare/${UPSTREAM_BRANCH}...${FORK_OWNER}:${FORK_DEFAULT_BRANCH}" \
--jq "{ahead_by: .ahead_by, owner_commits: ([.commits[] | select(.author.login == \"${FORK_OWNER}\")] | length)}"
```
Record `owner_commits` (capped at 30 by the scoring formula) and `ahead_by` (used in the article narrative, not scored). The compare endpoint returns up to 250 commits — more than enough; if `ahead_by > 250`, treat owner_commits as a lower bound and note it. If the call returns 404 (deleted fork), 422 (no common ancestor), or 409 (empty repo): record `owner_commits: 0, ahead_by: 0` and continue.
6. **Detect new skills** added by each fork owner. For each active fork, list the contents of `skills/` against their default branch:
```bash
gh api "repos/${FORK_FULL_NAME}/contents/skills?ref=${FORK_DEFAULT_BRANCH}" --jq '[.[] | .name]'
```
Compare against upstream's skill directory names (scan this repo's `skills/` locally). Any skill names in the fork but not upstream count as **new skills**. Cap at 5 per fork to prevent mass-rename gaming. If the fork has no `skills/` dir (404), record `new_skills: []`.
7. **Score each contributor** using this formula:
- `+10` per merged upstream PR (authored by the contributor)
- `+5` first-time-contributor bonus (one-time, applies if any of their PRs is `FIRST_TIME_CONTRIBUTOR` — first PRs are the highest-leverage signal)
- `+3` per opened-but-not-merged upstream PR
- `+2` per upstream PR review comment they left (capped at 20)
- `+1` per authored commit to their own fork (capped at 30)
- `+5` per new skill file detected in their fork (capped at 5)
- `+1` per star on their fork (was +2 — halved to reduce star-farm gaming; cap at 20 stars)
Rank all contributors by score descending. A contributor is anyone who either owns an active fork OR has authored an upstream PR in the past 30 days OR has left ≥1 upstream review comment in the past 30 days (union of all three sets).
8. **Compare to last week's leaderboard.** Glob `articles/fork-contributor-leaderboard-*.md` from the last 14 days, pick the most recent, and parse its ranked list (logins + scores) using a tolerant regex on the table rows (`^\| \d+ \| @(\S+) \| (\d+) \|`). If parsing yields zero rows, skip the comparison silently (don't crash). Compute week-over-week rank changes (new entries, rank shifts ≥3, dropouts).
9. **Write the article** to `articles/fork-contributor-leaderboard-${today}.md`. Lead with the narrative — the table is the proof, not the headline:
```markdown
# Fork Contributor Leaderboard — ${today}
*${N_CONTRIBUTORS} contributors moved ${TARGET_REPO} this week across ${N_FORKS} active forks, ${N_UPSTREAM_PRS} upstream PRs, and ${N_REVIEW_COMMENTS} review comments.*
## Movement This Week
*3–5 short paragraphs telling the story ofMention/keyword sweep on social platforms for [REPLACE: KEYWORDS] — trends, sentiment, top posts
5 concrete real-life actions, leverage-scored against open loops with specificity and anti-fluff gates
Curated AI-agent tweets, clustered into narratives with insight summaries
Tracker of AI agent substitution signals — which roles, companies, and industries show real headcount displacement. Named roles + real deployments only.
Competitive-intelligence digest on the AI agent framework space — momentum, releases, breaking changes across a curated watchlist
Cross-domain market pulse from AIXBT's free grounding endpoint — crypto, macro, tradfi, geopolitics. Refreshes taxonomy references (clusters, chains) as a bonus.
Pre-batch API provider health check — detects credit exhaustion or auth failure for every configured provider key before the scheduled batch runs, giving the operator a window to act before skills degrade
List a wallet's live ERC-20 token approvals on Base and flag unlimited / risky spender grants. Keyless via Base RPC (eth_getLogs + eth_call) — no explorer key needed.