Thanks for considering a contribution. InfraLens is a small, focused tool — the fastest way to get a PR merged is to keep changes just as focused.
For anything beyond a small fix (a new check, a UI redesign, a behavior change), please open an issue first to discuss the approach. It saves everyone rework.
These aren't up for debate in a PR — they're the reason this project exists in its current shape:
- No SaaS drift. No accounts, no billing, no orgs, no persistent server-side storage of analysis results. Ephemeral server-side, capped local (
localStorage) history only. - Passive analysis only. No exploitation, no brute force, no port scanning, no injection, no deep crawling, no internal network access. If a check needs anything beyond reading what a normal visitor's browser or DNS resolver could already see, it doesn't belong here.
- SSRF protection is never negotiable. Every new outbound request to a user-supplied target must go through the existing validated/pinned resolution path (
src/infralens/lib/security/). Never weaken or bypass it to make a test pass. - No invented certainty. Heuristic findings (stack detection, WAF/CDN fingerprinting) must be labeled with their actual confidence and must never silently affect the score.
InfraLens lives inside the randy-code repository — there's no separate
InfraLens repo to clone anymore.
git clone https://github.com/Randy-R-code/randy-code.git
cd randy-code
pnpm install
pnpm devOpen http://localhost:3000/tools/infralens. Requires Node 22+ and pnpm — this project doesn't use npm or yarn.
- Create a branch off
main. - Keep the PR to one thing. A bug fix doesn't need a drive-by refactor; a new check doesn't need to touch five unrelated files. Changes to InfraLens shouldn't touch unrelated parts of the portfolio, and vice versa.
- Add or update tests alongside the change —
pnpm test. Pure logic (scoring, parsing, formatting) should be unit tested; if you're touching a check, follow the existing pattern insrc/infralens/lib/checks/checks/*.test.ts. If the change affects a real user flow (not just logic), add or update an E2E spec undere2e/infralens/— see below. - Run the full gate before opening the PR:
pnpm check # lint + typecheck + test + build — same as CI - Keep TypeScript strict — no
anyused to silence an error, no global ESLint-disable comments. A narrowly-scopedeslint-disable-next-linewith a reason is fine when there's a real reason (see existing examples).
pnpm exec playwright install --with-deps chromium webkit # once
pnpm e2e:infralense2e/infralens/ uses Playwright against a real dev server, deliberately not mocked — this project has a habit of finding real bugs this way that mocked unit tests can't catch (a silent HTML5 form-validation deadlock on the URL input, several false-positive security findings from live header fingerprinting, and others — see CHANGELOG.md). It runs on dedicated infralens-desktop/infralens-mobile Playwright projects, single worker: the analysis flow is rate-limited per IP via the shared Upstash-backed policy (5 requests/minute burst, 30/hour), and parallel workers hitting the same local server would collide on that limit. Only e2e/infralens/analysis.spec.ts triggers a real analysis (against example.com) — keep it that way rather than adding a second spec that also does, or the two will race each other.
Each check is an independent module in src/infralens/lib/checks/checks/, implementing the shared CheckRunner interface (src/infralens/lib/checks/types.ts). Before adding one:
- Decide honestly whether it can be scored (
pass/warning/fail) or is inherently a heuristic/informational signal (info, never affecting the score) — seeisScoredStatusinscoring-config.ts. - If a lookup can fail for a reason outside the target's control (a third-party API being down, a resolver timeout), that's
unavailable, notfail. If the check itself throws, that'serror, not a bad configuration. - Add the check to the shared mock list in
run-checks.test.tsif it does its own network/DNS calls — every check-level module doing independent I/O needs a matching mock there. - Document it in
app/tools/infralens/docs/page.tsxin the same PR — a check without documentation isn't done.
Conventional commits, lowercase everywhere (type, subject, body bullets):
feat: short summary
- what changed and why it matters
- ...
Don't open a public issue for a vulnerability — see SECURITY.md.
Be respectful, assume good faith, keep disagreements about the code, not the person.