This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Three principles govern every decision in this project — for AI assistants, human maintainers, and anyone proposing changes:
-
Contributors first. This project exists for first-time contributors. Every decision should minimise friction, provide clear feedback, and keep the experience as close to real-world Git/GitHub practice as possible.
-
Minimum maintainability. The goal is zero required maintainer intervention for normal card submissions. Automation should handle the full lifecycle. Maintainer time is precious — don't create processes that require regular manual attention.
-
Simplicity. No over-engineering. Prefer the simpler solution. Aggressively question whether added complexity is justified. Three lines of clear code beats a clever abstraction. When in doubt, do less.
These three principles exist in tension with each other (automation = complexity; security = friction). Always resolve that tension by asking: what is the minimum intervention that keeps the contributor experience smooth and the maintainer burden low?
An educational open-source project that teaches first-time contributors how to use Git and GitHub. Contributors add a personal card by submitting a single HTML file via pull request. A bot validates and auto-merges valid submissions.
npm run prettier-html # Format index.html with Prettier
npx html-validate index.html cards/template.html # Validate HTML locallyThere are no test commands. CI checks Prettier formatting and HTML validation on every PR.
- Contributor copies
cards/template.htmltocards/<github-username>.html, fills it in, opens a PR validate-card-pr.ymltriggers on any PR touchingcards/*.htmlorindex.htmlscripts/validate-card-pr.jsfetches the card from the PR head (never checks out PR code), runsscripts/validate-card.js, posts a comment, then either auto-merges or exits 1- After merge,
card-to-archive.ymltriggersscripts/card-to-archive.jswhich parses the card, appends it to the latestarchive/json/archive_N.json(max 50 entries per file, creates a new file if full), updatesarchive/archiveFilesTotal.js, then deletescards/<username>.html
Each card is a standalone HTML fragment with this shape:
<div class="card">
<p class="name">...</p>
<p class="contact"><!-- <i> icon + <a> link pairs --></p>
<p class="about">...</p>
<div class="resources">
<ul>
<!-- <li><a> items -->
</ul>
</div>
</div>scripts/validate-card.js enforces this in phase 2 mode: name non-empty/non-placeholder, about non-empty, at least one contact link with a real href, resources (optional) max 5 with real hrefs.
archive/manifest.json— auto-generated;{ files: [...], totalArchivedCards: N }archive/json/archive_N.json— arrays of card objects{ name, contacts, about, resources }assets/main.js— fetches manifest, lazy-loads archive files in batches of 3 viaIntersectionObserver, shows contribution count immediately from manifest; loads all remaining files on search focus; also handles night mode, search highlighting, and scroll-to-topindex.html— static shell;#contributionsgrid is empty on load, populated entirely bymain.js
Node.js automation only — not browser code:
scripts/validate-card-pr.js— called by the GitHub Actions workflow; orchestrates validation, commenting, merging, and archive dispatchscripts/validate-card.js— pure validation logic, exportable; used by validate-card-pr.jsscripts/card-to-archive.js— convertscards/<filename>.htmlto JSON and appends to the archive
ci.yml— runs on all PRs; checks Prettier formatting on changed files and HTML validation on changed.htmlfilesvalidate-card-pr.yml—pull_request_targettrigger (runs base-branch code only, never PR code); validates and auto-merges card PRscard-to-archive.yml— triggered viaworkflow_dispatchafter merge (primary) orpull_request_target: closed(fallback); runs the archive script and commits the resultstale.yml— closes stale issues/PRs on a schedule
prettier.config.js: print width 120, single quotes, no semicolons, 2-space indent, trailing commas (ES5), LF line endings. Markdown files are excluded from Prettier formatting (.prettierignore).
html-validate rules (.htmlvalidate.json): self-closing void elements, double-quoted attributes, doctype required. A separate config in cards/.htmlvalidate.json relaxes rules for card fragments (no doctype required).