github-contribution-wall
Create a GitHub contribution wall image from a user's contribution history. Use when the user wants a GitHub contribution graph, contribution wall, heatmap, 2D poster, or 3D contribution visualization, including custom duration, light/dark theme, and color palette variants.
GitHub Contribution Wall
Create a polished GitHub contribution wall as an image. Support both a flat 2D heatmap and a 3D block version.
Resources
demo.png: visual reference image for composition and styling. If this file exists next toSKILL.md, inspect it before rendering and treat it as the primary style reference unless the user explicitly asks for something different.
Workflow
0) Inspect the visual reference first
If ./demo.png exists in the skill directory, inspect it before asking questions or rendering.
Use it to guide:
- overall composition
- camera angle
- chart scale
- legend placement
- background treatment
- spacing and margins
- typography weight and hierarchy
Follow the reference image closely for look and layout, while still respecting:
- the user's explicit preferences
- the requested
2dor3dmode - the required date range
- the requirement that
3doutput remainsisometric
If the reference image conflicts with the user's explicit instructions, follow the user.
1) Collect only the missing inputs
First inspect the user's prompt. If it already contains any of the answers below, do not ask that question again.
Required inputs:
- GitHub username
- Duration / date range
- Output style:
2dor3d - Theme mode:
lightordark - Color palette
If any inputs are missing, ask only for the unresolved ones. Keep the message short and practical. It is acceptable to ask all missing items in one message.
Use these defaults and choices when the user does not specify them:
- Duration choices:
last 3 months,last 6 months,last 12 months,year to date, orcustom - Style choices:
2dor3d - Theme choices:
lightordark - Palette choices:
classic greenocean bluesunset orangerose pinkmono graymultiple palettes
User-supplied preferences always override these defaults.
Default visual preferences:
- For
3d, the overall style must beisometric - For
3d, include the literal keywordisometricin any render brief or helper prompt you compose - For
3d, use a 45-degree horizontal viewing angle with a moderate elevation - For
3d, do not show ticks, axes, grid lines, axis labels, or axis frames - For
3d, place the legend at the bottom of the image - For
3d, render the legend as separate small 3D bars instead of flat swatches - For
3d, make every legend bar use the same square cross-section as the chart bars - For
3d, keep all bars fully opaque and non-transparent - For
3d, scale the chart up so the main wall dominates the canvas - Use a background that matches the selected palette and
lightordarkmode - Do not print an explicit
Legendheading
When demo.png is available, prefer its visual decisions over these defaults unless that would violate the user's explicit request.
If the user chooses custom duration, ask for the exact start and end dates.
If the user chooses multiple palettes, render multiple final images, one per palette.
2) Resolve the date range
Convert the chosen duration into an explicit date range before fetching data.
Rules:
- Always state the final date range explicitly in the output.
- Prefer full local dates in
YYYY-MM-DD. - For
last 12 months, use a rolling window ending today. - For
last 12 months, fetch the full range from exactly 12 months ago through today, not an abbreviated recent subset. - For
year to date, use January 1 of the current year through today. - When calling APIs, convert the range to explicit ISO datetimes so the full interval is preserved.
3) Try the direct render API first
Prefer the hosted ssr-contributions-img API as the first implementation path.
Repository:
https://github.com/CatsJuice/ssr-contributions-img
If you need deeper API customization such as theme selection, fully custom colors, gap tuning, or other render parameters, read the upstream documentation in this repository instead of guessing unsupported parameters.
Hosted endpoint:
https://ssr-contributions-svg.vercel.app/_/<username>?<queryString>
On this path, do not fetch GitHub contribution data yourself first. The API only needs the GitHub username and query parameters.
Map user choices to API parameters:
2d->chart=calendar3d->chart=3dbarlight/darkmode ->dark=false/dark=true- Built-in palette ->
theme=<themeName> - Custom palette ->
colors=<hex1>,<hex2>,...which overridestheme
Recommended defaults for the API path:
format=pngwhen you want to composite the chart onto a custom background and add your own labelsjpegonly if you specifically want the API to return an opaque white-background rasterquality=2forpngorjpeg- For
3d, enable outlines withstrokeWidthand optionallystrokeColor - For
3d, prefergradient=falseunless the reference image clearly uses gradient shading - For more advanced API controls such as theme variants, fully custom color sets, and gap tuning, consult
https://github.com/CatsJuice/ssr-contributions-img
Recommended API query construction:
2dexample:
https://ssr-contributions-svg.vercel.app/_/CatsJuice?chart=calendar&format=png&theme=green&dark=false&weeks=26
3dexample:
https://ssr-contributions-svg.vercel.app/_/CatsJuice?chart=3dbar&format=png&theme=dark&dark=true&weeks=26&strokeWidth=1.2&strokeColor=111827
Duration mapping for the API path:
last 3 months-> about13weekslast 6 months-> about26weekslast 12 months-> a full year usually needs about52to54weeks
Important limitation:
- According to the upstream README, the
weeksparameter supports1to50 - If the user requests an exact
last 12 monthsoutput, the API path may not be able to represent the full span exactly - In that case, use the API path only if the user accepts an approximation; otherwise fall back to the local rendering path below
If the API returns a suitable image:
- Use it directly as the chart body, or
- Composite it onto a larger final canvas with your own background, title, date range, and legend treatment
If the API is unavailable, rate-limited, fails, or cannot satisfy the requested duration or layout, continue with the local fallback path below.
4) Fetch contribution data for the local fallback path
Only do this when the API-first path is unavailable or unsuitable.
Prefer GitHub CLI first. Use a direct GitHub page fallback only if gh is unavailable or unusable.
Preferred path: gh api graphql
Use GitHub GraphQL to fetch the contribution calendar:
gh api graphql -f query='
query($login: String!, $from: DateTime!, $to: DateTime!) {
user(login: $login) {
contributionsCollection(from: $from, to: $to) {
contributionCalendar {
totalContributions
weeks {
contributionDays {
contributionCount
contributionLevel
date
weekday
color
}
}
}
}
}
}' -F login=USERNAME -F from=START_ISO -F to=END_ISO
Use full-day bounds for the request:
START_ISO: start date atT00:00:00ZEND_ISO: end date atT23:59:59Z
Target structure:
- 7 rows for weekdays
- N columns for weeks
- Each day needs at least:
datecontributionCountcontributionLevel
Fallback path: fetch from GitHub pages
Try one of these in order:
https://github.com/users/<username>/contributions?from=<start>&to=<end>https://github.com/<username>
Parse the contribution graph from the returned SVG or page markup. Extract day cells and their counts or intensity levels. If the HTML is used, inspect the contribution rect elements and related labels/tooltips. Normalize the result into the same day-based structure used by the gh path.
If both methods fail, stop and explain exactly what failed.
5) Normalize the data for rendering
Prepare a weekly grid:
- Columns are weeks from left to right
- Rows are weekdays from top to bottom
- Missing leading or trailing days are allowed as empty cells
- Preserve every returned week column. Do not crop, compress, or downsample weeks.
Duration sanity checks:
last 12 monthsshould usually render about 52 to 54 weekly columns- If the output looks closer to 8 to 10 columns, treat that as a failure and fix the fetch or layout before finishing
For each day, keep:
datecountlevelweek_indexweekday_index
For 3D output, derive a render height from count.
Recommended height mapping:
- Use a capped or square-root scale so a few high-count days do not dominate the chart.
- Example:
height = max(1, round(sqrt(count)))for non-zero cells. - Zero-count cells should stay at height
0.
6) Render with implementation paths in priority order
Try these implementation paths in order.
Before rendering, write a short internal render brief that includes:
- username
- explicit date range
2dor3dlightordark- palette
- the literal keyword
isometricfor3d - the key visual traits taken from
demo.pngwhen available
Option A: Direct third-party API render
Preferred as the first implementation path.
Use the hosted ssr-contributions-img service:
https://contribution.oooo.so/_/<username>?<queryString>
Rules:
- Do not fetch GitHub contribution data in advance on this path
- Build the output from
usernameplus API query parameters - Use
chart=calendarfor2d - Use
chart=3dbarfor3d - Use
themeanddarkwhen the requested look matches built-in API themes - Use
colorswhen you need a custom palette; this overridestheme - Prefer
format=pngso you can composite the returned chart on your own themed background - Use
qualitywhen outputtingpngorjpeg - For
3d, usestrokeWidthand optionallystrokeColorso cube outlines remain visible - If the service supports legend rendering for the requested chart, prefer the service-rendered legend first
Composition rules for the API path:
- If the API output already matches the requested final look, you may deliver it directly
- Prefer the third-party service's built-in legend when it matches the requested layout and style
- If you still need title text, explicit date range, a custom background, or additional layout adjustments, composite the returned image onto a larger final canvas locally
- Only replace or augment the API-rendered legend locally when the built-in legend cannot satisfy the requested position, style, or overall composition
- Preserve the API-rendered chart as the main body of the final composition
- When embedding the API-generated image into a larger composition, ensure it is integrated cleanly into the final design
- Do not leave any extra background patch, border, outline, frame, or boxed panel around the embedded chart
- Avoid visible seams, cutout edges, or collage-like stitching; the final image should feel like one unified piece
Duration rules for the API path:
- Convert duration presets into
weekswhen possible - Remember that the upstream API documents
weeksas1to50 - If the user requests an exact
last 12 monthsresult, do not silently compress it into a shorter-looking chart - Fall back to a local renderer when the API cannot represent the requested span accurately enough
Option B: Pillow to PNG
Preferred for the local fallback path, especially for 3d.
2D:
- Use square cells with small gaps.
- Draw one rectangle per day with
ImageDraw.rectangle. - Keep the grid centered and large on the canvas.
3D:
- Draw simple isometric cubes or columns with polygons.
- Keep the overall visual style isometric.
- Use a 45-degree horizontal projection.
- Compute isometric screen coordinates from each day's
(col, row)grid position:
x = origin_x + (col - row) * bw // 2
y = origin_y + (col + row) * bh // 2
- Treat
bwandbhas the projected block width and height used by the isometric grid. - Build each day as 3 polygons: top face, left face, and right face.
- Draw faces with
ImageDraw.polygon(). - Sort cubes back-to-front before drawing so nearer cubes paint over farther cubes.
- Outline every visible face.
- Trace polygon edges with
ImageDraw.line(). - Use a dark stroke color. A semi-transparent dark stroke is acceptable for edges, but cube faces must remain opaque.
- Keep all bars opaque. Do not use transparency.
- Keep each bar footprint square in the x/y plane.
- Keep perspective modest and readable instead of dramatic.
- Do not draw axes, ticks, grid lines, or axis labels.
- Put a compact 3D-style legend at the bottom without a
Legendheading. - Render the legend as separate 3D bars with the same square cross-section as the main chart bars.
Option C: matplotlib to PNG
Use if Pillow is missing or the polygon-based approach fails.
2D:
- Use square cells with small gaps.
- Draw one rectangle per day.
- Keep the grid centered and large on the canvas.
3D:
- Use
mpl_toolkits.mplot3dandbar3d. - Use bar height based on normalized count.
- Keep the overall visual style isometric.
- Use a 45-degree horizontal viewing angle.
- Prefer an orthographic or low-perspective look if the toolkit allows it.
- Draw visible edges on every block.
- Keep edge lines darker than the face color for separation.
- Keep all bars opaque. Do not use transparency.
- Keep each bar footprint square in the x/y plane.
- Hide axes, ticks, grid lines, and axis labels.
- Include a compact bottom legend because height is not self-evident.
- Render the legend as separate 3D bars, not a continuous strip.
- Use the same square cross-section for legend bars as for the main chart bars.
- Do not add a
Legendtitle or heading.
Option D: Python-generated SVG, then convert to image
Use if raster plotting libraries are unavailable.
Process:
- Generate SVG from Python.
- Convert to PNG with
cairosvgif available. - If conversion tools are unavailable, try a local system conversion path.
Keep this path simple. Do not build a complex rendering stack when a basic SVG is sufficient.
7) Apply themes and palettes
Respect both theme mode and palette choice.
Theme rules:
light: light background, dark labelsdark: dark background, light labels- The background should not be a flat unrelated color.
- Use a subtle background image, gradient, or low-contrast textured field derived from the same palette family as the chart.
- Keep the background quieter than the chart so the wall remains dominant.
Suggested palettes:
classic green: GitHub-like green rampocean blue: slate to cyan-blue rampsunset orange: warm amber-orange ramprose pink: dusty pink to red rampmono gray: neutral grayscale ramp
For each palette, define 4 or 5 non-zero intensity steps plus one zero-value background cell color.
When using the API path:
- Prefer
themewhen a built-in theme is a close match - Prefer
colorswhen you need exact palette control - Remember that
colorsoverridestheme - Prefer
pngplus local compositing when you need a custom palette-linked background image
If the user asks for multiple palettes:
- Render one final image per palette
- Keep layout, size, and labeling consistent across outputs
8) Compose the final image
The chart must be the main subject.
Layout requirements:
- Put the GitHub username at the top
- Show the exact date range under or near the title
- Keep the contribution wall centered
- Make the wall occupy most of the image area
- Avoid large empty margins
For 3D output:
- Use a larger overall chart scale than the 2D version
- Avoid large empty areas around the wall
- Include a compact bottom legend
- Render the legend samples as 3D bars
- Separate legend bars into distinct individual columns
- Make legend bar footprints square, matching the main chart bars
- Explain either the count buckets or the height mapping
- Do not show an explicit
Legendlabel - Keep the legend outside the main chart body
For long ranges such as last 12 months:
- Allocate enough horizontal space for the full weekly span
- Do not crop the leftmost or rightmost weeks
- If necessary, widen the canvas or reduce gaps before reducing the visible date span
Optional metadata:
- Total contributions in the selected range
- Palette name
2Dor3Dlabel
9) Quality rules
Before finishing, verify:
- Username is correct
- Date range is correct and printed on the image
- Grid orientation is correct
- The chart is visually centered
- The chart fills most of the canvas
- 3D blocks have visible outlines
- 3D blocks are opaque and not transparent
- 3D style reads as isometric
- Text is readable against the background
- Exported image is not cropped or blurry
For last 12 months, also verify:
- The chart shows roughly 52 to 54 weekly columns
- The image does not look like only the most recent 2 months
- The full requested date span is visible in both the data and the composition
For the API path, also verify:
- The generated URL parameters match the requested style and duration
- The API did not silently return a shorter-looking chart than requested
- If the API image is only the chart body, the final composition still includes the required labels and background treatment
If the result looks too small, increase cell size and reduce padding before trying a new design.
Practical defaults
Use these defaults unless the user requests otherwise:
- Output format:
png - Canvas:
2d: landscape, around1600x9003d: landscape, around2200x13003dforlast 12 months: prefer an extra-wide layout, around2400x1300or wider
- Typography: simple sans-serif
- Filename format:
github-contribution-wall-<username>-<start>-to-<end>-2d-<palette>.pnggithub-contribution-wall-<username>-<start>-to-<end>-3d-<palette>.png
Response behavior
When starting:
- Briefly confirm the resolved inputs
- Mention whether you are using the direct API path or the local fallback path
- If the style is
3d, explicitly describe it asisometric
When finishing:
- State what was generated
- State which implementation path succeeded
- Include the output file path or paths
- If multiple palettes were requested, list every generated image
If blocked:
- Say which step failed
- Include the exact missing dependency or fetch failure
- Do not claim the wall was generated unless the image file exists
You might also like
Academic Report Writer
Write structured academic reports, research papers, and scholarly documents with proper citations, methodology sections, and academic formatting.
Auto Research
Run bounded autonomous code experiments on a user-provided repository with a stable automated metric. Use when the user wants iterative improve-measure-keep-or-revert loops such as tuning training scripts, benchmark solvers, evaluable agent workflows, or performance/code-quality experiments. Do not use for open-ended product development, tasks without a reliable automated metric, or broad multi-file refactors.
Daily RSS Podcast
Generate a daily RSS podcast. Fetches latest articles from multiple RSS/Atom feeds, AI generates podcast script, uses ElevenLabs for TTS and mixes with BGM to produce final audio. Trigger: User says "generate today's podcast", "generate RSS podcast", "daily podcast". Not applicable for: Pure RSS reading, news summaries (when no audio output is needed).
ePub Translator
Translate ePub e-books between languages while preserving formatting, images, and structure.
Linear
Managing Linear issues, projects, and teams. Use when working with Linear tasks, creating issues, updating status, querying projects, or managing team workflows.
Postcard Designer
Design beautiful digital postcards with custom layouts, typography, and images using HTML/CSS. Create greeting cards and invitations.