') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - basilalshukaili/github-rep: Analyze any GitHub profile and score its reputation across 9 dimensions with honest, prioritized fixes. No bots, no fake stars. pip install github-rep · GitHub
Skip to content

Repository files navigation

github-rep

PyPI versionPython versionsCILicense: MIT

Score any GitHub user's reputation across 11 honest signals and get a prioritized fix list — in under 30 seconds.


Why this exists

GitHub profiles are the de-facto developer resume. Most advice on building GitHub reputation is either vague ("just contribute more") or gameable (spam-stars, low-effort PRs). This tool measures the signals that actually matter to recruiters, maintainers, and other developers — and tells you exactly what to fix first, ordered by impact.


Install

pip install github-rep

Requires Python 3.9+. No configuration needed — works unauthenticated (60 req/hr) or with a GitHub token for 5000 req/hr.


Quickstart

# Analyze any GitHub user
github-rep analyze-profile torvalds
# Use a token to avoid rate limitsexport GITHUB_TOKEN=ghp_yourtoken
github-rep analyze-profile sindresorhus
# Machine-readable JSON output
github-rep analyze-profile gvanrossum --json
# Show all findings, including low-priority ones
github-rep analyze-profile octocat --verbose
# Compare multiple profiles side by side
github-rep compare torvalds gvanrossum sindresorhus
# Check your API rate limit
github-rep rate-limit

Sample output

$ github-rep analyze-profile torvalds
╭──────────────────────────────── GitHub Profile ─────────────────────────────╮
│ @torvalds | Linus Torvalds │
│ │
│ Followers: 305,509 | Public repos: 12 | Stars earned: 246,028 │
╰──────────────────────────────────────────────────────────────────────────────╯
Grade: B (78/100)
Tier: Active developer
Score Breakdown
┏━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┓
┃ Dimension ┃ Score ┃ Max ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━┩
│ Profile Completeness │ 4 │ 10 │
│ Readme Quality │ 12 │ 15 │
│ Star Signal │ 20 │ 20 │
│ Contribution Streak │ 15 │ 15 │
│ Repo Diversity │ 7 │ 10 │
│ Description Quality │ 10 │ 10 │
│ Topic Tags │ 0 │ 5 │
│ Fork Ratio │ 5 │ 5 │
│ Recent Activity │ 5 │ 10 │
│ Release Cadence │ 0 │ 5 │
│ Profile Readme │ 0 │ 5 │
└──────────────────────────┴────────┴───────┘
Priority fixes:
[HIGH] Missing bio
Your bio is empty. It is the first thing visitors read.
Fix: Write 1-2 sentences: your focus, what you build, your superpower.
What is working:
[GOOD] Strong star signal (246028 total, top repo: 235147)
[GOOD] Active recent commits (0d ago)
[GOOD] All repos have descriptions

Grades: A (≥80) · B (≥65) · C (≥50) · D (≥35) · F


The 11 scored dimensions

#DimensionMax ptsWhat it measures
1Profile Completeness10Name, bio, avatar, location, website / social link
2README Quality15Top repo README length, code examples, install instructions
3Star Signal20Total stars earned across all repos (log-scaled)
4Contribution Streak15Days since last profile activity
5Repo Diversity10Number of public repos and language breadth
6Description Quality10Fraction of repos with meaningful descriptions
7Topic Tags5Repos tagged with relevant GitHub topics
8Fork Ratio5Proportion of original work vs. forked repos
9Recent Activity10Repos with pushes in the last 90 days
10Release Cadence5Published GitHub Releases on top repos
11Profile README5Presence and quality of the username/username profile README

Total: 100 points.

Dimensions 10 and 11 are new in v0.2.0 and measure signals that indicate a polished, production-ready presence — publishing versioned releases and curating a profile page.


All flags

github-rep analyze-profile <username> [OPTIONS]
FlagDescription
--jsonMachine-readable JSON output (all scores + findings)
--verbose / -vShow all findings including low-priority improvements
--token / -tGitHub PAT (also reads GITHUB_TOKEN env var)
--top NNumber of top repos to deep-analyze (default: 10)
--helpShow help and exit

JSON output

github-rep analyze-profile gvanrossum --json
{
"username": "gvanrossum",
"total": 72,
"grade": "B",
"tier": "Active developer",
"breakdown": {
"profile_completeness": 8,
"readme_quality": 12,
...
},
"findings": [
{
"category": "topic_tags",
"severity": "medium",
"title": "Most repos have no topic tags",
"detail": "Missing from GitHub Explore category pages entirely.",
"fix": "Add topics to your top 3 repos today - GitHub UI, takes 2 minutes."
}
]
}

Caching

Results are cached for 5 minutes under ~/.cache/github-rep/ to avoid hitting rate limits when running the tool multiple times. Delete the cache directory to force a fresh fetch.


FAQ

Do I need a GitHub token? No. Unauthenticated usage gets 60 API requests per hour — enough for a single profile analysis. Set GITHUB_TOKEN to get 5000 requests per hour and avoid hitting limits when comparing many profiles.

How is the score calculated? Each dimension is scored independently against fixed max points (totalling 100). There is no machine learning or relative ranking — the score reflects the absolute presence or absence of each signal.

Can I game the score? You could game every individual metric, but you would also genuinely improve your GitHub presence in the process. The signals are chosen because they correlate with real reputation value.

Why does a well-known developer score lower than expected? Some high-reputation developers (including Linus Torvalds) score below 80 because they skip signals like topic tags, profile READMEs, or GitHub Releases. The tool measures profile hygiene signals, not absolute influence.

How often should I re-run this? After each batch of improvements. Treat it like npm audit — run it, fix the findings, move on.


Contributing

See CONTRIBUTING.md. Bug reports and improvements welcome — open an issue on github.com/basilalshukaili/github-rep.


License

MIT — see LICENSE.

About

Analyze any GitHub profile and score its reputation across 9 dimensions with honest, prioritized fixes. No bots, no fake stars. pip install github-rep

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages