Skip to content

feat(scoring): count languages from contributed repos, not just owned#39

Open
rainer-friederich wants to merge 1 commit into
Younesfdj:masterfrom
rainer-friederich:feat/contributed-language-diversity
Open

feat(scoring): count languages from contributed repos, not just owned#39
rainer-friederich wants to merge 1 commit into
Younesfdj:masterfrom
rainer-friederich:feat/contributed-language-diversity

Conversation

@rainer-friederich

Copy link
Copy Markdown

Closes #38.

Problem

Language diversity (the Dribbling / "Technical range" stat) is scored only over ownerAffiliations: OWNER, isFork: false repos, so a developer whose work lives in organisations they don't personally own scores 0 languages — even with thousands of commits, PRs and reviews (all of which score fine, because they come from contributionsCollection). Owning a repo is only one way to work in a language.

Fix

Score languages over the union of:

  • the user's owned repos (as before), and
  • the public repos they've recently committed to (contributionsCollection.commitContributionsByRepository),

deduped by repo. A contributed repo counts only when it is public, non-fork, has a GitHub-classified primary language, and has ≥ MIN_CONTRIBUTED_LANG_COMMITS (3) commits in the last year — so a single drive-by typo fix to a big polyglot repo can't inflate diversity.

Honest limitation (documented in the issue): GitHub only exposes private activity as a bare restrictedContributionsCount — no repo, no language — so private work still can't be counted. This narrows the gap for org/team devs; it doesn't close it.

Shape of the change

  • lib/github/client.ts — profile query now also selects commitContributionsByRepository { contributions { totalCount } repository { nameWithOwner isFork isPrivate primaryLanguage { name } } } (one extra field on the already-fetched contributionsCollection, so no extra request). normalize() builds a deduped languageRepos union.
  • RawPayload.repos now feeds only the star signals; the new RawPayload.languageRepos feeds the language count + ranking.
  • lib/github/signals.tslanguages and rankLanguages() read languageRepos. Existing markup/styling demotion is unchanged, so a real language still headlines the card.

No change to the public card shape, scoring weights, or the language→logo catalog.

Tests

npm test → 116 passing (13 files). New coverage:

  • tests/signals.test.ts — the signal decoupling: languages come from languageRepos, stars from repos; the no-owned-public-repos (org-dev) case now scores languages; empty union → 0; markup demotion preserved.
  • tests/client.test.ts — the query includes commitContributionsByRepository; the union folds contributed public repos and dedupes them against owned repos; forks / private repos / sub-threshold (<3 commits) / unclassified repos are excluded.

npm run lint (0 new warnings) and npm run build (types + prod build) both pass.

Verification against a real account

Ran the new query/normalize logic against a live 11-year account that currently renders 0 languages: it now resolves JavaScript (headline) + Makefile from its public org contributions — 0 → a real profile.


🤖 Generated with Claude Code

Language diversity was scored only over a user's `ownerAffiliations: OWNER,
isFork: false` repos, so a developer whose work lives in organisations they
don't personally own (very common for professionals) scored "0 languages" —
even with thousands of commits.

Score languages over the UNION of owned repos and the public repos the user
has recently committed to (contributionsCollection.commitContributionsByRepository),
deduped by repo. A contributed repo counts only when it's public, non-fork,
has a GitHub-classified primary language, and has at least
MIN_CONTRIBUTED_LANG_COMMITS (3) commits in the last year, so a single
drive-by fix can't inflate diversity. Private work stays a bare contribution
count in GitHub's API, so it remains uncountable — this narrows the gap for
org/team devs, it doesn't claim to close it.

`repos` now feeds only the star signals; the new `languageRepos` feeds the
language count + ranking. Covered by tests/signals.test.ts (signal decoupling)
and new cases in tests/client.test.ts (query, threshold, fork/private/null
exclusion, owned-vs-contributed dedup).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Language diversity shows "0 languages" for developers who work in orgs they don't own

1 participant