The pagination guard broke on seen >= maxPerRepo, so a cap of 0 stopped
before the first page and rendered empty productive-time,
productive-weekday and most-commit-language cards. That inverted the
meaning 0 carries for top-repos, where it already means unlimited.
Treat a cap of 0 or less as no cap. Verified against a real repo: a cap
of 100 still stops at 100, while 500 and 0 both walk the full 382-commit
history.
Quarterly windows were not enough for the busiest quarter: a live run
warned that 2026-04-01..2026-06-30 still came back at the 100-repo
ceiling, so its seed list was truncated and those repos never got
probed for commit history.
Re-ask a saturated quarter month by month and merge only the repo
lists. The quarter has already contributed its calendar days and commit
totals, so the month passes skip that fold; verified by forcing the
ceiling down to 20 and confirming all six calendar-derived cards stay
byte-identical. Warn only when a month itself saturates, since there is
no finer window left to ask for.
Split each contribution year into quarterly windows.
commitContributionsByRepository caps at 100 repos per query and drops
the remainder without signalling it, which a prolific year hits: 2026
returned exactly 100 where the quarterly union returns 108. Warn when a
window still comes back at the ceiling instead of reporting a complete
list.
Add -include-org-repos / include_org_repos so org-owned repos the user
administers count toward stars, repo count, repos-per-language and
top-starred. Off by default, since enabling it moves those totals for
every existing caller. Commit-driven cards already covered org repos
through the seed list. Org repos carrying only read or write access are
dropped via viewerPermission.
Rename Profile.PublicRepos to RepoCount and drop "public" from the card
label: the count tracks the fetch filters and includes private repos
whenever the token can see them.
* feat(card): configurable start of week for heatmap + weekday cards
New -start-of-week CLI flag (and start_of_week action input) rotates the
contribution-heatmap rows and the productive-weekday bars so users whose
calendars start on Monday (or any other day) get matching output. Default
stays Sunday to preserve existing renders.
* docs: note start-of-week in design-guidelines, codebase-summary, deployment-guide
- design-guidelines: heatmap row order + productive-weekday bar order now derive from Profile.WeekStart
- codebase-summary: list new weekday_start_test.go cases + TestParseWeekday
- deployment-guide: mention start_of_week as an optional action input in the workflow template
Five new cards, all derived from data FetchProductive / FetchProfile already
pull, so zero additional API calls:
- contributions-heatmap: 7×53 calendar grid with a 5-bucket intensity ramp
mixed from each theme's Background→Accent so palettes with no dedicated
heat ramp still render sensibly.
- streak: current streak, longest streak with date ranges, active/total days.
- contributions-by-year: one bar per active year, peak year highlighted.
- productive-weekday + -all-time: 7-bar day-of-week mirror of the hour-of-day
cards; FetchProductive now also fills Weekday / WeekdayAllTime histograms
during the same commit-history pass.
- top-starred-repos: top 5 owned non-fork repos by stargazer count; threads
Stars through RepoInfo.
Card count: 9 → 14. Registered in allCards grouped by recency (last-year
block, then all-time block). Render test extended to cover all new files
and realistic daily-series inputs.
N8 — the field is set from contributionsCollection.contributionCalendar,
a rolling last-year window, not a lifetime total. Rename + updated
comment makes the semantics explicit so future readers don't confuse
it with TotalCommitsAllTime.
- I1 — donut chart with a single slice (100%) now renders via two
concentric <circle> elements instead of a degenerate SVG arc that
drew nothing. Reproduced with a standalone probe; regression test
added separately.
- I2 — FetchContributionsAllTime logs a warn to stderr when a year's
query returns nil user data so callers notice partial results
instead of rendering an empty all-time card silently.
- I6 — attributeCommit() receives the repo's byte total precomputed
once per repo rather than re-summing language edges for every
commit in the inner loop.
- I3 — update FetchOptions doc to describe zero-value vs CLI-flag defaults.
- I5 — release workflow gates docker/binaries on a test job; tags no
longer ship broken artifacts.
- N1 — replace handwritten joinErrs with strings.Join.
- N3 — truncate() now backs up to a UTF-8 rune boundary so error
messages never end on a split codepoint.
- N4 — pin Docker base images (golang:1.26-alpine, alpine:3.21) to
SHA256 digests.
- N5 — pin third-party GitHub Actions to commit SHAs with version
comments for readability.
- N9 — drop the "(non-fork)" qualifier from the stats card label; the
underlying GraphQL doesn't actually filter forks, so the phrasing
was misleading.
Replace the top-10-starred sampling with a seed list built from
contributionsCollection.commitContributionsByRepository, unioned across
every active contributionYear. Commit-history probes now land only on
repos where the user actually committed, covering all owned repos plus
forks and repos owned by others when allowed.
New visibility knobs (default off — public-facing READMEs stay
safe):
- -include-forks / include_forks : include forked repos
- -include-private / include_private: include private repos (requires
PAT with repo scope)
Compatibility:
- -top-repos default changed 10 → 0 (unlimited); still usable as a cap
for fast local runs.
- commitHistoryQuery now takes $owner so probes can target forks or
repos outside the user's ownership.
- FetchProfile now accepts FetchOptions; PublicRepos counts only repos
that pass the visibility filter.
Seed-list approach mirrors github-profile-summary-cards' own repo
sourcing but keeps our byte-weighted commit attribution.
Four time-bounded cards ("last year") now have all-time counterparts, and
the stats card gains a lifetime commits row.
New cards:
- 6-most-commit-language-all-time.svg (byte-weighted, all lifetime commits)
- 7-productive-time-all-time.svg (hour histogram over all lifetime commits)
- 8-contributions-all-time.svg (area chart spanning every active year)
Data pipeline:
- Drop the "since" filter from commitHistoryQuery; FetchProductive now
paginates unbounded commits and splits each commit into last-year and
all-time buckets in a single pass — no extra API calls.
- New contributionYearQuery iterates user.contributionYears to
concatenate calendar data and accumulate TotalCommitsAllTime.
- -commits-per-repo default bumped 100 → 500 to give all-time depth.
Polish:
- Productive-time title embeds the configured tz as "UTC±N.NN" (e.g.
UTC+7.00) on both last-year and all-time cards.
- Contribution x-axis flipped to mm/yy with an "mm/yy" footer caption
paralleling productive-time's "hour of day".
- Contribution x-axis label stride now targets ~6 labels regardless of
bucket count so the all-time chart (~100 months) stays readable while
the underlying curve still samples every month.
New 5-contributions.svg renders the last year's contribution calendar
as a monthly smooth-filled area chart. Pure Go SVG; no extra API calls
— one additional contributionCalendar.weeks block in the existing
profile GraphQL query carries the data.
- Y-axis mirrored on both sides with nice ticks.
- X-axis labels in YY/MM format, every other month to avoid overlap.
- Smooth curve via Catmull-Rom interpolation converted to cubic Bezier
(d3.curveCatmullRom default tension 0.5).
- Missing months between first and last are inserted as zero-count so
the chart stays time-continuous.
Each commit now contributes a full "vote" partitioned across the repo's
languages proportional to linguist byte counts, instead of crediting only
the primary language. A 60% Go / 40% Python repo adds 0.6 to Go and 0.4
to Python per commit.
- RepoInfo gains []LangEdge capturing the full byte breakdown already
returned by profileQuery.
- FetchProductive distributes each commit via a fixed-point scaleFactor
(int64 preserved, percentages unchanged in the card).
- Fallback to primary language only when linguist reports zero bytes
(empty repo).
Caveat: linguist excludes prose languages (Markdown, AsciiDoc, reST) from
its byte output, so Markdown-heavy repos still skew toward the detected
code fraction. Fixing that case requires per-commit file classification
via REST /commits/{sha} + go-enry — tracked as future work.
- Productive time is now a 24-hour bar chart with axes and nice tick labels
instead of a 7x24 heatmap. Model Productive field reshaped from
[7][24]int to [24]int.
- Language cards render as donut charts with a left-side legend instead of
a stacked bar. Slices beyond top-6 collapse into an "Other" row.
- Add niceTicks helper (1/2/5 * 10^k ladder, d3-style) for axis ticks.
- Legacy language_bar.go removed.
Align card set with github-profile-summary-cards' 5-card layout:
0-profile-details.svg (unchanged)
1-repos-per-language.svg (new) owned repos grouped by primary language
2-most-commit-language.svg (new) last-year commits attributed to each repo's primary language
3-stats.svg (renumbered)
4-productive-time.svg (renumbered)
- FetchProductive now fills p.CommitsByLanguage from the same commit history
it uses for the heatmap, so no extra API calls are introduced.
- TopRepos carries primary language so productive-time can aggregate by lang.
- LangStat.Bytes renamed to Value (repo count or commit count, context-dependent).
- Shared bar+legend renderer extracted to language_bar.go.
- Ignore generated output/ directory.
- Add GraphQL client fetching profile, stats, language aggregation, and
per-repo commit histograms for the productive-time heatmap.
- Render real SVG cards (profile details, top languages, stats grid,
weekday×hour heatmap) with XML escaping and thousands-formatted numbers.
- Expand theme palette to 30 built-ins ported from github-readme-stats;
add -list-themes, multi-theme rendering, and 'all' shortcut.
- Package as Docker-based GitHub Action (action.yml, Dockerfile,
entrypoint.sh) with optional auto-commit of generated cards.
- Release workflow publishes GHCR image and cross-platform binaries on
v* tags.
- Unit tests cover rendering, XML escape, number formatting, language sort.