GitGambit
One Place for a Developer's Public GitHub Story

Problem
Reviewing a developer's real impact on GitHub means juggling profile, PR list, diff, and comment tabs - and own-repo commits hide the signal in cross-org OSS work. Recruiters and maintainers need external contributions, review quality, and activity patterns in one view, without building a custom script or burning API quota on every refresh.
Approach
GitGambit (package github_analyzer) is a Next.js 16 App Router app that ingests a username via GitHub GraphQL (profile, up to 18 pages of PRs, 9 of issues, 5 of contributed repos) plus REST for per-PR file diffs. Results normalize into a ProfileBundle, cache in SQLite with stale-while-revalidate semantics, and render across routes: overview KPIs and heatmaps, org/repo drill-down, in-app PR viewer with unified/split diff modes and session-persisted viewed files, insights tab with archetype + composite score, timeline, and /compare for up to three profiles. Local watchlist (saved_users) tracks last-visited timestamps to surface what's new.
At a glance
PR depth
Up to ~900 / profile
GitGambit Score
5 sub-scores
Archetypes
8 rule-based
Compare
3 users max
Cache TTL
1h fresh · 24h max
Routes
9 App Router pages
Tech decisions
GraphQL bundle + REST diffs
GraphQL aggregates PRs, issues, reviews, and calendar in fewer round-trips; REST /pulls/files returns patch hunks diff2html needs.
SQLite profile + PR diff caches
Personal tool model - no Redis required; merged PR diffs are immutable and stored permanently keyed by repo#number.
External-first classification
PRs where owner ≠ username are the clearest OSS signal; overview dashboard leads with external merged count.
Slim RSC payloads for repo sidebar
Full PRNode bodies/comments stripped to SlimPR in project trees - MB-scale profiles shrink to tens of KB.
Heuristic archetype + score (no AI)
Deterministic, explainable labels for hiring screens; thresholds documented and tunable in lib/archetype.ts and lib/gitgambit-score.ts.
Inflight dedupe on cold profile fetch
Layout + page both request the same bundle; Map-based coalescing avoids duplicate GraphQL bursts on cache miss.