Skip to main content
ClaudeWave
Skill510 estrellas del repoactualizado today

Contributor Leaderboard

The Contributor Leaderboard ranks developers by their activity across a fork ecosystem and upstream repository, measuring commits to personal forks, pull requests sent upstream, code reviews, and first-time contributions. Use this weekly to publicly recognize contributors with no other reward signal and create visibility for work that the upstream project values but does not automatically celebrate.

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/aaronjmars/aeon /tmp/contributor-leaderboard && cp -r /tmp/contributor-leaderboard/skills/contributor-leaderboard ~/.claude/skills/contributor-leaderboard
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.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/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/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 of the week.