The dracula sample under output/dracula/ was a reference render for the README. Now that demo/ auto-generates every card × every theme on each push, the sample is redundant — and keeping it trackers means every behavioral tweak shows up as a diff in committed SVGs. - Delete output/dracula/*.svg. - .gitignore: collapse `output/*` + `!output/dracula/` to a plain `output/`. - demo.yml: drop `output/**` from paths-ignore (no longer part of any push). - README / docs: point readers at demo/ instead of output/dracula/.
8.6 KiB
Project Roadmap
Phase 0 — Skeleton (✅ done)
- Module layout, flag parsing, placeholder SVG renderers.
Phase 1 — Five core cards (✅ done)
- Profile details, repos-per-language, most-commit-language, stats, productive-time.
- GraphQL profile query + per-repo commit history.
- Docker-based Action wrapper, release workflow, 65-theme palette.
Phase 2 — Chart quality (✅ done)
- Match github-profile-summary-cards visual style (donuts, 24h bar chart, proper axes).
- Octicon labels on profile + stats cards.
- Smooth area chart for contributions (Catmull-Rom → cubic Bezier).
Phase 3 — All-time variants (✅ done)
- Unified commit-history fetch splits into last-year and all-time buckets.
- Per-year
contributionsCollectionloop yieldsDailyContributionsAllTime+TotalCommitsAllTime. - Three new cards: most-commit-language-all-time, productive-time-all-time, contributions-all-time.
- Stats card gains a lifetime commits row.
Phase 4 — Accurate repo sampling (✅ done)
- Seed list built from
commitContributionsByRepositoryacross every active year. -include-forks/-include-privatevisibility flags (defaults later flipped on in Phase 7).-top-reposdemoted to an optional cap (default 0 = unlimited).- Commit-history query takes
$ownerso forks and non-owned repos are probeable.
Phase 5 — Byte-weighted attribution (✅ done)
- Each commit distributes fractionally across repo's language bytes, not just primary.
- Improves mixed-code repo accuracy; still inaccurate for Markdown-heavy repos (linguist prose-exclusion).
Phase 6 — Code-review remediation (✅ done)
Follow-up after the full-project review (plans/reports/code-review-260418-2223-full-project.md):
- Donut chart's single-slice (100%) rendering no longer produces an empty arc.
FetchContributionsAllTimewarns on stderr when a year returns nil user data.attributeCommitreceives a precomputed per-repo byte total instead of re-summing every commit.Profile.TotalContributions→TotalContributionsLastYear(accurate semantics).context.Contextthreaded through all fetchers;-timeoutflag (default 30m); Ctrl-C cancels in-flight requests.- Rate-limit awareness: on 429 or exhausted primary limit, honor
Retry-After/X-RateLimit-Resetup to 5 min and retry once. - Release workflow gates docker + binaries on a test job; no more shipping broken tags.
- Docker base images and third-party GitHub Actions pinned to SHA with version comments.
- Stats card label "Contributed to (non-fork)" corrected to "Contributed to" (the query doesn't filter forks).
- Tests: fixed stale XML-escape assertion, added
TestDonutSingleSlice, addedTestUTCOffsetLabelfor half-hour zones.
Phase 7 — Release polish & Marketplace publish (✅ done)
- Visibility defaults flipped on:
-include-forks,-include-privatenow defaulttrue(private silently no-ops if token lacks scope). - Output filenames dropped the numeric prefix:
0-profile-details.svg→profile-details.svgetc. Embedders reference by name. - Card dimensions shrunk
500×220→340×200to match github-profile-summary-cards so two cards fit per row in a README. - Action
action.ymlname set toghstats-cardsfor Marketplace (the bareghstatsis taken); repo staystiennm99/ghstats. v1.0.0,v1.1.0,v1.1.1tagged and released. Prebuilt binaries (linux/darwin/windows × amd64/arm64) ship with each; Docker image pushed toghcr.io/tiennm99/ghstats.- Floating
v1major tag created;release.ymlhas anupdate-major-tagjob that force-movesv1to the latest patch after test+docker+binaries pass, so consumers pinned totiennm99/ghstats@v1auto-pick new releases. - README badges (Marketplace / Release / License) + direct Marketplace link for cross-navigation.
- Repo topics expanded for Marketplace discoverability (
ghstats-cards,profile-readme,stats-cards, etc.). - An attempted repo rename to
tiennm99/ghstats-cardswas committed and reverted (commits399a3dc+8bd2128on record) — GHCR path immutability and the cost of breaking pinned consumers outweighed the Marketplace-name cosmetic benefit.
Phase 7.6 — S-tier breadth cards (✅ done)
Five new cards that ride on data already fetched — zero extra API calls:
contributions-heatmap— canonical 7×53 calendar grid with a theme-derived 5-bucket intensity ramp.contributions-by-year— one bar per active year, peak year highlighted.productive-weekday+productive-weekday-all-time— mirror the hour-of-day pair;FetchProductivenow also fillsWeekday/WeekdayAllTimehistograms.top-starred-repos— top 5 owned non-fork repos by ⭐; required threadingStarsthroughRepoInfo.streak— current + longest streak + active days/total. Pure post-processing ofDailyContributionsAllTime.
Card count: 9 → 14. FetchProductive still pays for commit-history pagination once; the new cards are pure renderers.
Phase 7.5 — Demo gallery for theme discovery (✅ done)
- New
.github/workflows/demo.ymlrenders every card for every theme against the repo owner's profile on each push tomain. - Output lands in
demo/<theme>/, with an auto-generateddemo/README.mdTOC so reviewers can browse palettes side-by-side with real data instead of cloning and running the CLI. - Loop prevention: workflow skips pushes that only touch
demo/**,**.md, orLICENSE;GITHUB_TOKEN-driven pushes don't retrigger workflows by design. - Consumer impact: none — this is a repo-internal discovery aid, not a shipped feature.
Phase 8 — Per-commit file classification (planned)
Goal: fix the Markdown-blog misattribution case (and any repo where linguist's byte view disagrees with what files user actually edited).
Approach: GET /repos/{owner}/{repo}/commits/{sha} per commit → classify each file with go-enry. Weight by additions + deletions.
Cost: ~1 REST call per commit. At current defaults (30 seed repos × 500 commits = 15,000 commits worst case) this is heavy — needs -accurate-languages opt-in flag, schedule weekly not daily.
Research: see plans/reports/researcher-260418-2001-accurate-language-stats.md.
Status: designed, not implemented.
Phase 9 — Partial bare clone for lifetime all-repo stats (planned)
Goal: lifetime language stats across every repo a user has committed in, without the 500-commits-per-repo cap.
Approach: git clone --filter=blob:none --bare per seed repo + git log --author --numstat → go-enry.
Cost: ~5% of full-clone disk (trees only, no blobs); 3–5 minutes runtime for 100 repos; zero REST calls.
Trade-off: needs disk + git binary on runner. Lowlighter/metrics' indepth mode does similar but clones full blobs; we'd skip those.
Status: researched only; behind -deep flag when landed.
Phase 10 — User-configurable repo exclusion (planned)
Goal: let users drop throwaway repos (experiments, forks they stashed) from stats without disabling forks globally.
Approach: -exclude-repo owner1/name1,owner2/name2 flag. Filter seed list before probing.
Cost: negligible (client-side filter).
Status: pending user demand.
Phase 11 — Expand ownerAffiliations (planned)
Goal: catch work done in org repos where user is a collaborator, not owner (e.g., company monorepos).
Approach: expose -affiliations OWNER,COLLABORATOR,ORGANIZATION_MEMBER flag. Requires thinking about whether to display private org work on a public profile card.
Status: blocked on deciding the privacy default.
Known limitations (not roadmap items — by design)
| Limitation | Reason |
|---|---|
| Markdown/prose excluded from byte counts | Linguist's default; we defer to linguist |
| No real-time API | Scope: scheduled batch renderer, not a server |
| No WakaTime integration | Out of scope — WakaTime cards already exist (athul/waka-readme, anmol098/waka-readme-stats) |
| No heatmap (7×24) variant of productive time | Simplified to 24-hour bar chart to match reference project |
| Hard width of 340 px per card | Matches github-profile-summary-cards; customising would cascade through every chart's geometry. |
Tracked research reports
All in plans/reports/:
researcher-260418-2001-accurate-language-stats.md— metrics vs GRS vs go-enry feasibilityresearcher-260418-2012-profile-stats-survey.md— follow-up survey across 6 more toolsanalysis-260418-2140-most-commit-language-all-time.md— hand-reconstruction of tiennm99's card output, showing exactly why each language lands wherecode-review-260418-2223-full-project.md— adversarial review of the whole codebase; findings all closed in Phase 6