Skip to content

Commit d6f3195

Browse files
authored
feat: version 0.4.0 (#2)
* feat: version 0.4.0 * style: remove hover from packages
1 parent b977b2e commit d6f3195

55 files changed

Lines changed: 1425 additions & 134 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"hooks": [
77
{
88
"type": "command",
9-
"command": "printf '\\n📦 Agent Friendly Code — current release: 0.3.0\\n • Read AGENTS.md for conventions, CONTRIBUTING.md for the PR workflow.\\n • Roadmap: 0.4.0 (quick wins — history-aware signals + PR score-diff + Claude Code skill) → 0.5.0 (auto-refresh + smarter matching) → 0.6.0 (maintainer ownership + at-scale discovery) → 1.0.0 (production cut — Postgres + at-scale indexing + benchmark harness).\\n • Changelog rule: user-facing capabilities only. Codebase hygiene (CI / linter / tests / CONTRIBUTING) does NOT go in lib/changelog.ts.\\n'"
9+
"command": "printf '\\n📦 Agent Friendly Code — current release: 0.4.0\\n • Read AGENTS.md for conventions, CONTRIBUTING.md for the PR workflow.\\n • Roadmap: 0.5.0 (quick wins — history-aware signals + PR score-diff + Claude Code skill) → 0.6.0 (auto-refresh + smarter matching — webhook rescoring + alternatives v2) → 0.7.0 (maintainer ownership + at-scale discovery — OAuth opt-out + package overlay at scale) → 1.0.0 (production cut — Postgres + at-scale indexing + benchmark harness).\\n • Changelog rule: user-facing capabilities only. Codebase hygiene (CI / linter / tests / CONTRIBUTING) does NOT go in lib/changelog.ts.\\n'"
1010
}
1111
]
1212
}

.claude/skills/code-review/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Only `@phosphor-icons/react`. Block Lucide, Heroicons, React Icons, inline SVG,
5454
## Security
5555

5656
- Parameterised SQL only.
57-
- `dangerouslySetInnerHTML` is allowed only for the existing server-built JSON-LD scripts (`app/layout.tsx`, `app/page.tsx`, `app/repo/[id]/page.tsx`, `app/package/[registry]/[name]/page.tsx`) with the `<``<` escape preserved. Reject any new use.
57+
- `dangerouslySetInnerHTML` is allowed only for the existing server-built JSON-LD scripts (`app/layout.tsx`, `app/page.tsx`, `app/methodology/page.tsx`, `app/repo/[id]/page.tsx`, `app/package/[registry]/[name]/page.tsx`) with the `<``<` escape preserved. Reject any new use.
5858
- External links include `rel="noopener noreferrer"`.
5959
- Never execute code from a cloned repo.
6060

.claude/skills/quality-check/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Run the four checks below on any diff affecting UI or I/O. Report findings group
3939
## Security
4040

4141
- **SQL parameterisation**: every query uses `?` placeholders. No string concatenation.
42-
- **`dangerouslySetInnerHTML`** is allowed only for server-built JSON-LD (`app/layout.tsx`, `app/page.tsx`, `app/repo/[id]/page.tsx`, `app/package/[registry]/[name]/page.tsx`) and must keep the `<``<` escape. Any other use must be rejected.
42+
- **`dangerouslySetInnerHTML`** is allowed only for server-built JSON-LD (`app/layout.tsx`, `app/page.tsx`, `app/methodology/page.tsx`, `app/repo/[id]/page.tsx`, `app/package/[registry]/[name]/page.tsx`) and must keep the `<``<` escape. Any other use must be rejected.
4343
- **External URLs** in `<a target="_blank">` always include `rel="noopener noreferrer"`.
4444
- **User input at every boundary** is validated: `parseRepoUrl` for repo URLs, `Number.isFinite` for numeric params, length caps on search strings.
4545
- **Clone safety**: `git clone --depth 1 --single-branch`; never execute code from a clone (no `bun install`, no `npm install`, no post-clone scripts).

AGENTS.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,17 @@ app/
4343
page.tsx # leaderboard
4444
repo/[id]/page.tsx # repo detail with per-model suggestions (includes generateMetadata)
4545
methodology/page.tsx # how the static scoring works
46+
about/page.tsx # who built this and why (footer-linked, E-E-A-T)
4647
roadmap/page.tsx # upcoming versions (from lib/roadmap.ts)
4748
changelog/page.tsx # what's in this build (from lib/changelog.ts)
48-
robots.ts # /robots.txt — allows "/", disallows "/api/"
49-
sitemap.ts # /sitemap.xml — static routes + every repo detail page
49+
robots.ts # /robots.txt — wildcard + explicit AI-crawler allows
50+
sitemap.ts # /sitemap.xml — static routes + every repo detail page (priority scaled by score)
51+
llms.txt/route.ts # /llms.txt — markdown manifest for LLM crawlers (Perplexity, Claude, ChatGPT search)
5052
api/repos/route.ts
5153
api/repo/[id]/route.ts
5254
api/badge/[host]/[owner]/[name]/route.ts # SVG badge for README embeds (?model=<id> for per-model)
5355
api/package/[registry]/[name]/route.ts # npm/PyPI/Cargo lookup → source-repo score
56+
repo/[id]/opengraph-image.tsx # next/og convention — per-repo OG image (auto-wired)
5457
package/page.tsx # explainer + try-it examples
5558
package/[registry]/[name]/page.tsx # scored | not_scored | unresolved states
5659
globals.css # Tailwind import + @theme tokens (no custom utilities)
@@ -81,7 +84,7 @@ lib/
8184
changelog.ts # typed ChangelogEntry[]
8285
roadmap.ts # typed RoadmapVersion[]
8386
scripts/
84-
init-db.ts, score.ts, seed.ts, seed-list.ts
87+
init-db.ts, score.ts, seed.ts, seed-list.ts, seed-packages.ts (auto-runs after seed.ts)
8588
tests/
8689
_helpers.ts # makeFixture / removeFixture build synthetic trees under os.tmpdir()
8790
format.test.ts # compactStars, relativeTime, hostLabel
@@ -93,9 +96,10 @@ tasks/
9396
0.1.0/ # released — shipped record
9497
0.2.0/ # released — dogfood complete (tests, self-score, row-click)
9598
0.3.0/ # released — embeddable scores + broader coverage (badge, more agents, alternatives, package lookup)
96-
0.4.0/ # planned — quick wins (history-aware signals + PR score-diff action + Claude Code skill)
97-
0.5.0/ # planned — auto-refresh + smarter matching (webhook rescoring + alternatives v2)
98-
0.6.0/ # planned — maintainer ownership + at-scale discovery (OAuth opt-out + package overlay at scale)
99+
0.4.0/ # released — credible scores + discoverability (docs-cited rationales + agent-specific signals + About/llms.txt/OG)
100+
0.5.0/ # planned — quick wins (history-aware signals + PR score-diff action + Claude Code skill)
101+
0.6.0/ # planned — auto-refresh + smarter matching (webhook rescoring + alternatives v2)
102+
0.7.0/ # planned — maintainer ownership + at-scale discovery (OAuth opt-out + package overlay at scale)
99103
1.0.0/ # planned — production cut (Postgres + at-scale indexing + benchmark harness)
100104
.claude/
101105
settings.json # SessionStart + Stop hooks (Stop → hooks/stop-guard.sh)
@@ -176,9 +180,9 @@ Hooks docs: <https://docs.claude.com/en/docs/claude-code/hooks.html>.
176180

177181
- We `git clone --depth 1 --single-branch` arbitrary URLs — safe by default. We never run post-clone scripts, never `npm install`, never execute code from the clone.
178182
- SQL: all queries parameterised. No interpolation.
179-
- HTML: React auto-escapes. The only `dangerouslySetInnerHTML` is server-built JSON-LD with `<` escaped to `<` (`app/layout.tsx`, `app/page.tsx`, `app/repo/[id]/page.tsx`, `app/package/[registry]/[name]/page.tsx`); never feed user-controlled strings into it.
183+
- HTML: React auto-escapes. The only `dangerouslySetInnerHTML` is server-built JSON-LD with `<` escaped to `<` (`app/layout.tsx`, `app/page.tsx`, `app/methodology/page.tsx`, `app/repo/[id]/page.tsx`, `app/package/[registry]/[name]/page.tsx`); never feed user-controlled strings into it.
180184
- Local-path mode reads files; never writes outside `data/` and the clone workspace passed to `shallowClone`.
181-
- No auth yet (read-only dashboard). When auth lands (`tasks/0.6.0/01-opt-out-claim-flow.md`), do it via OAuth and gate DB writes per user.
185+
- No auth yet (read-only dashboard). When auth lands (`tasks/0.7.0/01-opt-out-claim-flow.md`), do it via OAuth and gate DB writes per user.
182186

183187
**Operational concerns** (not code-level security) worth flagging before public launch:
184188

@@ -188,7 +192,7 @@ Hooks docs: <https://docs.claude.com/en/docs/claude-code/hooks.html>.
188192

189193
## Things to leave alone
190194

191-
- Per-model weights are illustrative. Don't tune without `tasks/1.0.0/03-benchmark-harness.md`.
195+
- Per-model rationales are derived from each agent's published documentation (see `MODELS[].sources` in `lib/scoring/weights.ts`); the weights themselves are still pre-benchmark. Do not tune individual values without re-running the docs audit (see `tasks/0.4.0/01-sourced-agent-rationales.md`) or shipping the v1.0.0 benchmark harness.
192196
- SQLite schema is intentionally simple. Flag before restructuring.
193197
- The I/O boundary. Scoring stays pure; DB stays in `lib/db.ts`.
194198
- `APP_VERSION` — don't bump without a release.

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Agent Friendly Code
22

3-
[![Release](https://img.shields.io/badge/release-0.3.0-blue?style=flat-square)](./lib/changelog.ts)
3+
[![Release](https://img.shields.io/badge/release-0.4.0-blue?style=flat-square)](./lib/changelog.ts)
44
[![License: MIT](https://img.shields.io/badge/license-MIT-green?style=flat-square)](./LICENSE)
55
[![Next.js 16](https://img.shields.io/badge/Next.js-16-black?style=flat-square)](https://nextjs.org)
66
[![Node ≥20.9](https://img.shields.io/badge/node-%E2%89%A520.9-43853d?style=flat-square&logo=node.js&logoColor=white)](https://nodejs.org)
@@ -9,7 +9,7 @@
99

1010
**A public dashboard that ranks open-source repos by how friendly they are for AI coding agents — per model.**
1111

12-
Next.js 16 + SQLite (`better-sqlite3`), styled with Tailwind CSS 4. Spans GitHub, GitLab, and Bitbucket out of the box. Current release: **0.3.0**.
12+
Next.js 16 + SQLite (`better-sqlite3`), styled with Tailwind CSS 4. Spans GitHub, GitLab, and Bitbucket out of the box. Current release: **0.4.0**.
1313

1414
![Agent Friendly Code — leaderboard](./public/demo/light.png)
1515

@@ -60,9 +60,9 @@ Two audiences:
6060

6161
Not pretending the idea is free of risk:
6262

63-
- **Per-model scoring is the hardest part and the easiest to fake.** Today the weights are illustrative. Real "Claude ranks this higher than GPT-5" requires actually running each agent on each repo. That's `tasks/1.0.0/03-benchmark-harness.md`.
63+
- **Per-model scoring is the hardest part and the easiest to fake.** Per-model rationales are now sourced from each agent's published docs (see `MODELS[].sources` in `lib/scoring/weights.ts`), but the weight values themselves are still pre-benchmark. Real "Claude ranks this higher than GPT-5" requires actually running each agent on each repo. That's `tasks/1.0.0/03-benchmark-harness.md`.
6464
- **Factory.ai is already in this space.** Differentiation has to stay sharp.
65-
- **Public-shaming risk.** Ranking #47,823 without consent invites angry maintainers. Planned via `tasks/0.6.0/01-opt-out-claim-flow.md`.
65+
- **Public-shaming risk.** Ranking #47,823 without consent invites angry maintainers. Planned via `tasks/0.7.0/01-opt-out-claim-flow.md`.
6666
- **Score gaming.** Once public, people add boilerplate `AGENTS.md` to pass the rubric without being useful. Dynamic (actually-run-an-agent) checks are the counter — see benchmark harness.
6767
- **Freshness.** Scores decay with every push. Webhook-driven rescoring is roadmap.
6868

@@ -84,14 +84,14 @@ Short answer: **low risk**. The app:
8484
- Rate limiting the public API.
8585
- Sandbox the cloner in a container (future-proofing against hypothetical git CVEs).
8686

87-
Auth and per-maintainer controls land with the opt-out / claim flow in v0.6.0.
87+
Auth and per-maintainer controls land with the opt-out / claim flow in v0.7.0.
8888

8989
## Quickstart
9090

9191
```bash
9292
bun install
9393
bun run prepare-hooks # once — installs lefthook pre-commit (Biome + tsc + test + file-length)
94-
bun run seed # score the curated set across GH / GL / BB
94+
bun run seed # score the curated set across GH / GL / BB + cache popular package aliases
9595
bun run dev # http://localhost:3000
9696
```
9797

@@ -110,7 +110,7 @@ Run the unit tests with `bun run test` (uses `node --test` + `tsx`; requires Nod
110110

111111
## Versioning
112112

113-
`lib/version.ts` and `package.json` carry the current release number (currently **0.3.0**). Bumps happen only when we actually cut a release — never when merging intermediate work. The version pill in the header surfaces the number directly; `/changelog` lists what each release shipped.
113+
`lib/version.ts` and `package.json` carry the current release number (currently **0.4.0**). Bumps happen only when we actually cut a release — never when merging intermediate work. The version pill in the header surfaces the number directly; `/changelog` lists what each release shipped.
114114

115115
## Stack & rationale
116116

@@ -172,9 +172,9 @@ See `/roadmap` in the running app or the per-version `tasks/` folders for the fu
172172

173173
Versions are sequenced cheap-first so the highest-impact small additions don't get gated on heavy infra:
174174

175-
- **0.4.0 — quick wins**: history-aware signals (maintenance recency, commit velocity, contributor activity) + a GitHub Action that comments the score delta on every PR + a Claude Code skill (with public `/api/score` lookup) that recommends a model for the active repo. No new infra.
176-
- **0.5.0 — auto-refresh + smarter matching**: webhook-driven rescoring (keep scores fresh on every push) + alternatives via README embeddings (cross-language matches the v0.3.0 SQL heuristic misses).
177-
- **0.6.0 — maintainer ownership + at-scale discovery**: OAuth opt-out / claim flow for maintainers + at-scale package overlay (per-registry leaderboards + userscript that renders the badge inline on npmjs.com / PyPI / crates.io).
175+
- **0.5.0 — quick wins**: history-aware signals (maintenance recency, commit velocity, contributor activity) + a GitHub Action that comments the score delta on every PR + a Claude Code skill (with public `/api/score` lookup) that recommends a model for the active repo. No new infra.
176+
- **0.6.0 — auto-refresh + smarter matching**: webhook-driven rescoring (keep scores fresh on every push) + alternatives via README embeddings (cross-language matches the v0.3.0 SQL heuristic misses).
177+
- **0.7.0 — maintainer ownership + at-scale discovery**: OAuth opt-out / claim flow for maintainers + at-scale package overlay (per-registry leaderboards + userscript that renders the badge inline on npmjs.com / PyPI / crates.io).
178178
- **1.0.0 — production cut**: Postgres migration for concurrent writers + auto-discovered crawl (target 10k repos) + benchmark harness that derives per-model weights from measured agent success. From here on, breaking API changes require a MAJOR bump.
179179

180180
## Defensibility

app/about/page.tsx

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import type { Metadata } from "next";
2+
import Link from "next/link";
3+
4+
import { Panel, PanelHeading } from "@/components/Panel";
5+
import { APP_NAME, REPO_URL } from "@/lib/version";
6+
7+
export const metadata: Metadata = {
8+
title: "About",
9+
alternates: { canonical: "/about" },
10+
twitter: { title: `About — ${APP_NAME}` },
11+
openGraph: { title: `About — ${APP_NAME}`, url: "/about" },
12+
description: `Who built ${APP_NAME}, why it exists, and what it isn't. Independent, MIT-licensed, no affiliation with any AI agent vendor.`,
13+
};
14+
15+
export default function AboutPage() {
16+
return (
17+
<>
18+
<section className="my-3 mb-7">
19+
<h1 className="mb-2.5 text-[30px] font-bold leading-[1.18] tracking-tight">About</h1>
20+
<p className="m-0 max-w-[72ch] text-[15.5px] text-ink-dim">
21+
Who built {APP_NAME}, why it exists, and what it deliberately isn&apos;t.
22+
</p>
23+
</section>
24+
25+
<Panel>
26+
<PanelHeading>Who</PanelHeading>
27+
<p className="m-0 text-[14.5px] leading-relaxed text-ink-dim">
28+
Built and maintained by{" "}
29+
<a
30+
target="_blank"
31+
rel="noopener noreferrer"
32+
href="https://github.com/hsnice16"
33+
className="border-b border-dotted border-ink-dim/60 text-ink-dim hover:border-ink-soft hover:text-ink-soft"
34+
>
35+
Himanshu Singh
36+
</a>
37+
. Independent project — no affiliation with Anthropic, OpenAI, Google, Cognition, Anysphere, or any of the
38+
agent vendors ranked here.
39+
</p>
40+
</Panel>
41+
42+
<div className="mt-3.5">
43+
<Panel>
44+
<PanelHeading>Why this exists</PanelHeading>
45+
<p className="m-0 text-[14.5px] leading-relaxed text-ink-dim">
46+
The gap between &ldquo;repo with a README&rdquo; and &ldquo;repo that actually helps an AI coding agent ship
47+
code&rdquo; keeps widening, and there&apos;s no public way to tell who&apos;s doing the work. {APP_NAME}{" "}
48+
tries to make that visible — per model, because the agents aren&apos;t interchangeable. Claude Code wants an
49+
AGENTS.md and a fast test loop; Cursor wants strong types and a skim-readable README; Devin wants a runnable
50+
dev environment with declared deps and tests. The same repository can score very differently across them,
51+
and a single overall number would hide that.
52+
</p>
53+
</Panel>
54+
</div>
55+
56+
<div className="mt-3.5">
57+
<Panel>
58+
<PanelHeading>What it isn&apos;t</PanelHeading>
59+
<p className="m-0 text-[14.5px] leading-relaxed text-ink-dim">
60+
This is not a benchmark of agent performance. Today every score is derived from{" "}
61+
<strong className="text-ink">static signals</strong> — file existence and content-length checks on the
62+
cloned tree. No agent is actually run. Per-model rationales are derived from each agent&apos;s published
63+
documentation (sources are linked on the methodology page), but the weight values themselves are still
64+
pre-benchmark — not yet calibrated against measured agent success. Read the{" "}
65+
<Link
66+
href="/methodology"
67+
className="border-b border-dotted border-ink-dim/60 text-ink-dim hover:border-ink-soft hover:text-ink-soft"
68+
>
69+
methodology
70+
</Link>{" "}
71+
for the full picture, including the production-cut plan to replace pre-benchmark weights with measured ones.
72+
</p>
73+
</Panel>
74+
</div>
75+
76+
<div className="mt-3.5">
77+
<Panel>
78+
<PanelHeading>Open source</PanelHeading>
79+
<p className="m-0 text-[14.5px] leading-relaxed text-ink-dim">
80+
MIT-licensed. The signal definitions, weight profiles, scoring code, seed list, and every score in the
81+
database are all in the{" "}
82+
<a
83+
href={REPO_URL}
84+
target="_blank"
85+
rel="noopener noreferrer"
86+
className="border-b border-dotted border-ink-dim/60 text-ink-dim hover:border-ink-soft hover:text-ink-soft"
87+
>
88+
source repository
89+
</a>
90+
. If a repo&apos;s score looks wrong, file an issue with a link and the rubric to revisit; if a signal is
91+
missing, propose one.
92+
</p>
93+
</Panel>
94+
</div>
95+
96+
<div className="mt-3.5">
97+
<Panel>
98+
<PanelHeading>Contact</PanelHeading>
99+
100+
<p className="m-0 text-[14.5px] leading-relaxed text-ink-dim">
101+
Best signal: open an issue or discussion on{" "}
102+
<a
103+
target="_blank"
104+
rel="noopener noreferrer"
105+
href={`${REPO_URL}/issues`}
106+
className="border-b border-dotted border-ink-dim/60 text-ink-dim hover:border-ink-soft hover:text-ink-soft"
107+
>
108+
GitHub
109+
</a>
110+
.
111+
</p>
112+
</Panel>
113+
</div>
114+
</>
115+
);
116+
}

0 commit comments

Comments
 (0)