Skip to content

Commit 7d4bd34

Browse files
committed
feat: release v0.2.0
1 parent 0140dbe commit 7d4bd34

48 files changed

Lines changed: 1297 additions & 106 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.1.0\\n • Read AGENTS.md for conventions, CONTRIBUTING.md for the PR workflow.\\n • Roadmap: 0.2.0 (dogfood) → 0.3.0 (benchmark harness) → 0.4.0 (ecosystem integration) → 0.5.0 (alternatives) → 0.6.0 (registry overlay) → 0.7.0 (history-aware signals) → 1.0.0 (production stability) → 1.1.0 (at-scale GitHub indexing).\\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.2.0\\n • Read AGENTS.md for conventions, CONTRIBUTING.md for the PR workflow.\\n • Roadmap: 0.3.0 (benchmark harness) → 0.4.0 (ecosystem integration) → 0.5.0 (alternatives) → 0.6.0 (registry overlay) → 0.7.0 (history-aware signals) → 1.0.0 (production stability) → 1.1.0 (at-scale GitHub indexing).\\n • Changelog rule: user-facing capabilities only. Codebase hygiene (CI / linter / tests / CONTRIBUTING) does NOT go in lib/changelog.ts.\\n'"
1010
}
1111
]
1212
}

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ _Bulleted list of what this PR modifies. Keep it scoped to the summary._
1414

1515
## Testing
1616

17-
_How you verified this. Commands run (`bun run score <url>`, `bun x tsc --noEmit`, manual pass of specific pages). For UI changes: mobile + desktop, light + dark._
17+
_How you verified this. Commands run (`bun run test`, `bun run score <url>`, `bun x tsc --noEmit`, manual pass of specific pages). For UI changes: mobile + desktop, light + dark._
1818

1919
## Screenshots / screencasts
2020

.github/workflows/ci.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ concurrency:
1212

1313
jobs:
1414
check:
15-
name: Lint · Format · Typecheck
15+
name: Lint · Format · Typecheck · Test
1616
runs-on: ubuntu-latest
1717
steps:
1818
- uses: actions/checkout@v4
@@ -22,6 +22,11 @@ jobs:
2222
with:
2323
bun-version: 1.2.16
2424

25+
- name: Setup Node
26+
uses: actions/setup-node@v4
27+
with:
28+
node-version: "22"
29+
2530
- name: Install
2631
run: bun install --frozen-lockfile
2732

@@ -30,3 +35,6 @@ jobs:
3035

3136
- name: Typecheck
3237
run: bun x tsc --noEmit
38+
39+
- name: Test
40+
run: bun run test

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
22

AGENTS.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ See `README.md` for the full product narrative. See `tasks/` for per-version wor
2727

2828
```bash
2929
bun install
30-
bun run prepare-hooks # once — installs lefthook git hooks (Biome + tsc on pre-commit)
30+
bun run prepare-hooks # once — installs lefthook git hooks (Biome + tsc + test on pre-commit)
3131
bun run init-db # optional — auto-runs on first score
32-
bun run seed # score the curated set (~42 repos) across GH / GL / BB
32+
bun run seed # score the curated set (124 repos) across GH / GL / BB
3333
bun run dev # http://localhost:3000
3434
bun run score <url> # score a single repo
35+
bun run test # unit tests (node --test + tsx) — requires Node ≥20.9.0
3536
```
3637

3738
## Layout
@@ -54,7 +55,7 @@ components/ # Tailwind-styled React components
5455
HostPill.tsx, HostSelect.tsx, Medal.tsx, ModelPills.tsx,
5556
MobileNav.tsx, Pagination.tsx, SearchBar.tsx, SelectMenu.tsx, SortSelect.tsx,
5657
SignalRow.tsx, SuggestionItem.tsx, VersionPill.tsx,
57-
GoogleAnalytics.tsx
58+
BackToTop.tsx, GoogleAnalytics.tsx
5859
lib/
5960
constants/
6061
scoring.ts # score thresholds, visible limits
@@ -75,10 +76,16 @@ lib/
7576
roadmap.ts # typed RoadmapVersion[]
7677
scripts/
7778
init-db.ts, score.ts, seed.ts
79+
tests/
80+
_helpers.ts # makeFixture / removeFixture build synthetic trees under os.tmpdir()
81+
format.test.ts # compactStars, relativeTime, hostLabel
82+
parse-repo-url.test.ts # GH / GL / BB parsing + edge cases
83+
scorer.test.ts # scoreRepo, topImprovements
84+
signals/ # one *.test.ts per signal
7885
tasks/
7986
README.md
8087
0.1.0/ # released — shipped record
81-
0.2.0/ # planned — complete the dogfood
88+
0.2.0/ # releaseddogfood complete (tests, self-score, row-click)
8289
0.3.0/ # planned — real per-model weights (benchmark harness)
8390
0.4.0/ # planned — ecosystem integration (badge, PR diff, webhook, opt-out)
8491
0.5.0/ # planned — discovery (alternative recommender)
@@ -184,6 +191,7 @@ Hooks docs: <https://docs.claude.com/en/docs/claude-code/hooks.html>.
184191
## Useful pre-commit checks
185192

186193
- `bun run score https://github.com/honojs/hono` — end-to-end smoke.
194+
- `bun run test` — unit tests (Node ≥20.9.0 required).
187195
- `curl -s localhost:3000/api/repos | head` — verify persistence + API.
188196
- `bun x tsc --noEmit` — typecheck.
189197
- Manual pass over `/`, `/repo/:id`, `/methodology`, `/roadmap`, `/changelog` after UI changes.

CONTRIBUTING.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ Read [AGENTS.md](./AGENTS.md) first — it's the source of truth for stack, conv
88

99
```bash
1010
bun install
11-
bun run prepare-hooks # once — installs lefthook pre-commit (Biome + tsc)
12-
bun run seed # optional: populate the DB with the curated set (~42 public repos)
11+
bun run prepare-hooks # once — installs lefthook pre-commit (Biome + tsc + test)
12+
bun run seed # optional: populate the DB with the curated set (124 public repos)
1313
bun run dev # http://localhost:3000
14+
bun run test # unit tests (node --test + tsx) — requires Node ≥20.9.0
1415
```
1516

1617
## Branch naming
@@ -40,10 +41,11 @@ Don't squash-amend published commits. Don't skip hooks (`--no-verify`); if a hoo
4041

4142
## Pre-commit hook
4243

43-
`lefthook` runs two jobs on every commit:
44+
`lefthook` runs three jobs on every commit:
4445

4546
1. **Biome**`check --write` on staged JS/TS/JSON/CSS. Fixes and re-stages.
4647
2. **tsc**`--noEmit` on `*.{ts,tsx}`. Blocks commits that don't typecheck.
48+
3. **test**`bun run test` when any `*.{ts,tsx}` file is staged. Runs the full `node --test` suite (~1–2 s); blocks on regressions.
4749

4850
Run `bun run prepare-hooks` once after cloning. CI (`.github/workflows/`) runs the same checks on PR for belt-and-braces.
4951

@@ -62,17 +64,15 @@ New PRs auto-populate from [`.github/PULL_REQUEST_TEMPLATE.md`](./.github/PULL_R
6264

6365
## Motivation
6466

65-
<Why this change. Link to the roadmap item or `tasks/<file>.md`. If it's
66-
a roadmap item, quote the task's Goal line.>
67+
<Why this change. Link to the roadmap item or `tasks/<file>.md`. If it's a roadmap item, quote the task's Goal line.>
6768

6869
## Changes
6970

7071
<Bulleted list of what this PR modifies. Keep it scoped to the summary.>
7172

7273
## Testing
7374

74-
<How you verified this. Commands run (`bun run score <url>`, `bun x tsc --noEmit`,
75-
manual pass of specific pages). For UI changes: mobile + desktop, light + dark.>
75+
<How you verified this. Commands run (`bun run test`, `bun run score <url>`, `bun x tsc --noEmit`, manual pass of specific pages). For UI changes: mobile + desktop, light + dark.>
7676

7777
## Screenshots / screencasts
7878

README.md

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

3-
[![Release](https://img.shields.io/badge/release-0.1.0-blue?style=flat-square)](./lib/changelog.ts)
3+
[![Release](https://img.shields.io/badge/release-0.2.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)
77

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

10-
Next.js 16 + SQLite (`better-sqlite3`), styled with Tailwind CSS 4. Spans GitHub, GitLab, and Bitbucket out of the box. Current release: **0.1.0**.
10+
Next.js 16 + SQLite (`better-sqlite3`), styled with Tailwind CSS 4. Spans GitHub, GitLab, and Bitbucket out of the box. Current release: **0.2.0**.
1111

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

@@ -88,8 +88,8 @@ Auth and per-maintainer controls land with the opt-out / claim flow in v0.4.0.
8888

8989
```bash
9090
bun install
91-
bun run prepare-hooks # once — installs lefthook pre-commit (Biome + tsc)
92-
bun run seed # score the curated set (~42 repos) across GH / GL / BB
91+
bun run prepare-hooks # once — installs lefthook pre-commit (Biome + tsc + test)
92+
bun run seed # score the curated set (124 repos) across GH / GL / BB
9393
bun run dev # http://localhost:3000
9494
```
9595

@@ -104,9 +104,11 @@ bun run score /path/to/local/checkout
104104

105105
Optional: `GITHUB_TOKEN` / `GITLAB_TOKEN` in env to raise API rate limits.
106106

107+
Run the unit tests with `bun run test` (uses `node --test` + `tsx`; requires Node ≥20.9.0).
108+
107109
## Versioning
108110

109-
`lib/version.ts` and `package.json` carry the current release number (currently **0.1.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.
111+
`lib/version.ts` and `package.json` carry the current release number (currently **0.2.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.
110112

111113
## Stack & rationale
112114

@@ -148,9 +150,10 @@ lib/
148150
constants/ thresholds, host labels, sort keys
149151
utils/ format + score-tier helpers
150152
db.ts better-sqlite3 schema + queries (all SQL lives here)
151-
version.ts APP_NAME, APP_VERSION, APP_URL, APP_DESCRIPTION, REPO_URL
153+
version.ts APP_NAME, APP_VERSION, IS_PRE_RELEASE, APP_URL, APP_DESCRIPTION, REPO_URL
152154
changelog.ts / roadmap.ts
153155
scripts/ CLI entries run via `tsx` (Node) — score, seed, init-db
156+
tests/ `node --test` unit tests — scorer, signals, URL parser, formatters
154157
tasks/ Per-version task breakdown (agent-readable)
155158
public/ Static assets — demo/ screenshots used by the README + OG image
156159
.claude/ settings.json, hooks/ (Stop guard), skills/
@@ -166,7 +169,6 @@ LICENSE MIT
166169

167170
See `/roadmap` in the running app or the per-version `tasks/` folders for the full picture.
168171

169-
- **0.2.0 — complete the dogfood**: tests for scorer / signals / URL parser + self-score ≥ 90 on this repo's own rubric.
170172
- **0.3.0 — real per-model weights**: benchmark harness actually runs agents on scoped tasks per repo; current illustrative weights get replaced with measured ones.
171173
- **0.4.0 — ecosystem integration**: badge endpoint for READMEs, GitHub Action that comments score delta on PRs, webhook-driven rescoring, OAuth-gated opt-out / claim flow for maintainers.
172174
- **0.5.0 — alternative recommender**: "repo Y does the same thing and ranks higher for your model."

app/changelog/page.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default function ChangelogPage() {
1818
<>
1919
<section className="my-3 mb-7">
2020
<h1 className="mb-2.5 text-[30px] font-bold leading-[1.18] tracking-tight">Changelog</h1>
21+
2122
<p className="m-0 max-w-[70ch] text-[15.5px] text-ink-dim">
2223
What&apos;s shipped from the{" "}
2324
<Link href="/roadmap" className="text-ink-dim underline-offset-4 hover:text-ink-soft hover:underline">
@@ -27,26 +28,29 @@ export default function ChangelogPage() {
2728
</p>
2829
</section>
2930

30-
<Panel>
31+
<div className="flex flex-col gap-3.5">
3132
{CHANGELOG.map((entry) => (
32-
<div key={entry.label} className="border-b border-line py-6 first:pt-0 last:border-b-0 last:pb-0">
33+
<Panel key={entry.label}>
3334
<div className="mb-2.5 flex flex-wrap items-baseline gap-3.5">
3435
<span className="inline-block rounded-md border border-line bg-surface-2 px-2.5 py-[3px] font-mono text-[13px] font-semibold text-accent">
3536
{entry.label}
3637
</span>
38+
3739
<span className="mr-auto text-lg font-semibold tracking-tight">{entry.title}</span>
40+
3841
<span className="tabular-nums text-sm text-muted">{entry.date}</span>
3942
</div>
43+
4044
<ul className="m-0 pl-5 text-[14.5px] text-ink-dim">
4145
{entry.highlights.map((h) => (
4246
<li key={h} className="my-1">
4347
{h}
4448
</li>
4549
))}
4650
</ul>
47-
</div>
51+
</Panel>
4852
))}
49-
</Panel>
53+
</div>
5054
</>
5155
);
5256
}

app/layout.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { Metadata, Viewport } from "next";
22
import Link from "next/link";
33
import "./globals.css";
44

5+
import { BackToTop } from "@/components/BackToTop";
56
import { GoogleAnalytics } from "@/components/GoogleAnalytics";
67
import { MobileNav } from "@/components/MobileNav";
78
import { VersionPill } from "@/components/VersionPill";
@@ -108,6 +109,8 @@ export default function RootLayout({ children }: { children: React.ReactNode })
108109
empirically derived.
109110
</footer>
110111
</div>
112+
113+
<BackToTop />
111114
</body>
112115
</html>
113116
);

app/methodology/page.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export default function MethodologyPage() {
3535
enough to produce meaningfully different rankings and to show how the UX of per-model scoring feels, but it
3636
should not be read as a benchmark.
3737
</p>
38+
3839
<p className="mt-3 text-[14.5px] leading-relaxed text-ink-dim">
3940
The plan to replace illustrative weights with measured ones is the v0.3.0 milestone on the{" "}
4041
<Link href="/roadmap" className="text-ink-dim underline-offset-4 hover:text-ink-soft hover:underline">
@@ -56,6 +57,7 @@ export default function MethodologyPage() {
5657
overall = mean(per-model scores)
5758
improvement = closing a gap unlocks (1 - pass) × weight / Σweight × 100 points`}
5859
</pre>
60+
5961
<p className="mt-3 text-sm text-muted">
6062
<code className="rounded border border-line bg-surface-2 px-1.5 py-0.5 font-mono text-xs">signal.pass</code>{" "}
6163
is a float in [0, 1] — partial credit is allowed (e.g. a thin README gets 0.3, a long one gets 1.0).
@@ -66,6 +68,7 @@ improvement = closing a gap unlocks (1 - pass) × weight / Σweight × 100
6668
<div className="mt-3.5">
6769
<Panel>
6870
<PanelHeading>Signals ({SIGNALS.length})</PanelHeading>
71+
6972
<ul className="m-0 list-none p-0">
7073
{SIGNALS.map((s) => (
7174
<li
@@ -91,11 +94,13 @@ improvement = closing a gap unlocks (1 - pass) × weight / Σweight × 100
9194
<div className="mt-3.5">
9295
<Panel>
9396
<PanelHeading>Models & weight profiles ({MODELS.length})</PanelHeading>
97+
9498
<ul className="m-0 list-none p-0">
9599
{MODELS.map((m) => (
96100
<li key={m.id} className="border-b border-line py-3 last:border-b-0">
97101
<div className="text-[15px] font-medium">{m.label}</div>
98102
<div className="mt-1 text-[13.5px] text-ink-dim">{m.rationale}</div>
103+
99104
<details className="mt-2 text-[13px] text-muted">
100105
<summary className="cursor-pointer">Weights</summary>
101106
<pre className="mt-2 overflow-x-auto rounded-lg border border-line bg-surface-2 px-3 py-2 font-mono text-xs leading-relaxed">
@@ -116,7 +121,9 @@ improvement = closing a gap unlocks (1 - pass) × weight / Σweight × 100
116121
<ul className="m-0 ml-5 list-disc text-[14.5px] leading-relaxed text-ink-dim">
117122
<li>Whether tests actually pass (we only detect their presence).</li>
118123
<li>Whether the linter actually runs cleanly.</li>
124+
119125
<li>Whether the dev-env artifact (Makefile, Dockerfile) works end-to-end.</li>
126+
120127
<li>
121128
Commit-history signals — churn, commit frequency, contributor count. We use
122129
<code className="mx-1 rounded border border-line bg-surface-2 px-1 py-0.5 font-mono text-xs">
@@ -129,6 +136,7 @@ improvement = closing a gap unlocks (1 - pass) × weight / Σweight × 100
129136
</Link>
130137
.
131138
</li>
139+
132140
<li>How agents actually perform on the repo — that&apos;s the v0.3.0 benchmark harness.</li>
133141
</ul>
134142
</Panel>

0 commit comments

Comments
 (0)