Skip to content

Commit 5d332f1

Browse files
authored
feat: 0.5.0 task 02 - GitHub Action for score (#3)
1 parent f30a776 commit 5d332f1

31 files changed

Lines changed: 784 additions & 46 deletions

File tree

.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/methodology/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/action/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/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.
42+
- **`dangerouslySetInnerHTML`** is allowed only for server-built JSON-LD (`app/layout.tsx`, `app/page.tsx`, `app/action/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).
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
name: Bug report
3+
about: The dashboard showed something wrong, an API returned the wrong shape, scoring looks off, or `bun run dev` broke locally.
4+
title: "bug: <one-line summary>"
5+
labels: bug
6+
---
7+
8+
## What happened
9+
10+
_The behaviour you observed._
11+
12+
## What you expected
13+
14+
_What you thought would happen._
15+
16+
## Where
17+
18+
_Tick whichever applies:_
19+
20+
- [ ] Dashboard (visitor-facing — leaderboard, repo page, methodology, about, etc.)
21+
- [ ] API route (`/api/repo/:id`, `/api/repos`, `/api/score`, `/api/badge/...`, `/api/package/...`, `/llms.txt`)
22+
- [ ] Score / signal output (the score itself looks wrong for a specific repo)
23+
- [ ] Local dev (`bun run dev`, `bun run seed`, `bun run score <url>`, `bun run test`)
24+
- [ ] Other — please describe.
25+
26+
## Reproduction
27+
28+
- **URL or repo affected (if any)**: _e.g. `https://<deploy-host>/repo/123` or the repo being scored, like `vercel/next.js`._
29+
- **Browser / OS** (for UI bugs): _e.g. Chrome 130 on macOS 15._
30+
- **`bun --version` / Node version** (for local-dev bugs): _e.g. `bun 1.1.x`, `node 20.9.0`._
31+
- **Steps**:
32+
1. __
33+
2. __
34+
3. __
35+
36+
### Logs / screenshots
37+
38+
_Console output, server logs, or screenshots. Use a `<details>` block for long logs._
39+
40+
## Anything else
41+
42+
_Anything that might be relevant — recent re-score, specific signal, model selection, fresh install vs upgrade, etc._
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
name: Feature request
3+
about: Suggest a new signal, model, host, page, API field, or other capability.
4+
title: "feat: <one-line summary>"
5+
labels: enhancement
6+
---
7+
8+
## What you want
9+
10+
_The capability you'd like. Be concrete._
11+
12+
## Why
13+
14+
_The problem this solves. Who benefits — dashboard visitor, API caller, maintainer of a listed repo, contributor — and when._
15+
16+
## Alternatives considered
17+
18+
_What you've tried, or why a workaround on top of the existing surface isn't enough._
19+
20+
## Roadmap status
21+
22+
_Tick whichever applies:_
23+
24+
- [ ] On the roadmap already — version `0.X.0`, task file `tasks/0.X.0/NN-*.md`. (Linking the task file is enough; no further design needed here.)
25+
- [ ] Not on the roadmap. Proposing it for inclusion. (Maintainer call: add it to `lib/roadmap.ts` first, then a PR can land.)
26+
27+
## Scope check
28+
29+
_Tick whichever applies:_
30+
31+
- [ ] **New signal** — see "Adding a signal" in [AGENTS.md](../../AGENTS.md). Mirrors to the sibling `agent-friendly-action` repo.
32+
- [ ] **New model** — see "Adding a model" in [AGENTS.md](../../AGENTS.md). Mirrors to the sibling repo.
33+
- [ ] **New host** — see "Adding a host" in [AGENTS.md](../../AGENTS.md).
34+
- [ ] **New / changed API route**`/api/...`. Note breaking-change implications for action + agent-skill consumers.
35+
- [ ] **New page or UI surface**.
36+
- [ ] **Other** — please describe.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Agent-friendly score diff
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
7+
permissions:
8+
contents: read
9+
pull-requests: write
10+
11+
jobs:
12+
score-diff:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0
18+
- uses: hsnice16/agent-friendly-action@v0
19+
with:
20+
agents-badge-token: ${{ secrets.AGENTS_BADGE_TOKEN }}

AGENTS.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,21 @@ app/
5151
llms.txt/route.ts # /llms.txt — markdown manifest for LLM crawlers (Perplexity, Claude, ChatGPT search)
5252
api/repos/route.ts
5353
api/repo/[id]/route.ts
54+
api/score/route.ts # /api/score?host=&repo=owner/name — public lookup (powers the action + agent skill)
5455
api/badge/[host]/[owner]/[name]/route.ts # SVG badge for README embeds (?model=<id> for per-model)
5556
api/package/[registry]/[name]/route.ts # npm/PyPI/Cargo lookup → source-repo score
5657
repo/[id]/opengraph-image.tsx # next/og convention — per-repo OG image (auto-wired)
5758
package/page.tsx # explainer + try-it examples
5859
package/[registry]/[name]/page.tsx # scored | not_scored | unresolved states
60+
action/page.tsx # PR-diff GitHub Action explainer + install snippet (SEO landing for the sibling action repo)
5961
globals.css # Tailwind import + @theme tokens (no custom utilities)
6062
components/ # Tailwind-styled React components
6163
Panel.tsx, ScoreBar.tsx, ScoreNumber.tsx, ScoreCell.tsx,
6264
HostPill.tsx, HostSelect.tsx, Medal.tsx, ModelPills.tsx,
6365
MobileNav.tsx, Pagination.tsx, SearchBar.tsx, SelectMenu.tsx, SortSelect.tsx,
6466
SignalRow.tsx, SuggestionItem.tsx, VersionPill.tsx,
6567
RepoHero.tsx, SignalListCard.tsx, ModelSuggestions.tsx, PerModelScores.tsx,
68+
BadgeEmbed.tsx, ActionEmbed.tsx, CopySnippet.tsx, PackageLookupForm.tsx,
6669
BackToTop.tsx, GoogleAnalytics.tsx
6770
lib/
6871
constants/
@@ -80,7 +83,7 @@ lib/
8083
git.ts, github.ts, registries.ts # registries.ts: npm/PyPI/Cargo package → source-repo URL
8184
package-lookup.ts # shared registry → repo lookup (used by /api/package + /package page)
8285
db.ts # better-sqlite3 schema + queries
83-
version.ts # APP_NAME, APP_VERSION, IS_PRE_RELEASE, APP_URL, APP_DESCRIPTION, REPO_URL
86+
version.ts # APP_NAME, APP_VERSION, IS_PRE_RELEASE, APP_URL, APP_DESCRIPTION, REPO_URL, ACTION_REPO_URL, ACTION_USES
8487
changelog.ts # typed ChangelogEntry[]
8588
roadmap.ts # typed RoadmapVersion[]
8689
scripts/
@@ -130,17 +133,31 @@ Keep it that way when adding features. If a component needs data, fetch in the p
130133
- **Versioning + changelog**: bumps on `lib/version.ts` + `package.json` `version` happen only on a real release, coordinated with a new bucket in `lib/changelog.ts`. The changelog is a **user-facing capability log** — every bullet describes something a dashboard visitor or API caller can see, click, or call. Codebase hygiene (CI, linters, pre-commit, tests), pure internal refactors, dep bumps, and contributor-facing docs (CONTRIBUTING, PR templates) do **not** earn a changelog line — they stay in `tasks/` and the PR description. When a roadmap item ships, remove it from `lib/roadmap.ts` in the same PR — moved, not duplicated.
131134
- **File length**: `.ts` / `.tsx` under `app/`, `components/`, `lib/` stay ≤ 300 lines — enforced by the `file-length` pre-commit job in `lefthook.yml`. Near the cap, split into subcomponents or extract helpers to `lib/utils/`. `scripts/` is exempt (seed data lists).
132135

136+
## Sibling repos
137+
138+
The PR-diff GitHub Action lives in a sibling directory: `../agent-friendly-action/`. It **vendors** the scorer (`lib/scoring/` from this repo) into its own bundle so it can run inside maintainer CI with no network call to this app. Extracting `agent-friendly-scorer` as a standalone npm package is deferred to `tasks/1.0.0/03-benchmark-harness.md`, when a second sibling consumer (the benchmark harness) appears. Until then, the two copies of the scorer must stay in sync by hand.
139+
140+
**Whenever you change `lib/scoring/`** — adding a signal, tweaking a weight, refactoring `scorer.ts`, anything — also:
141+
142+
1. Re-vendor the changed file(s) into `../agent-friendly-action/src/scoring/` (mirror the directory layout).
143+
2. Append a line under "Unreleased" in `../agent-friendly-action/CHANGELOG.md` describing what changed, so action consumers can read what shipped in each tagged release.
144+
3. The action's CI verifies its `dist/` bundle is in sync with `src/` on every push, but it can't catch upstream-source drift — that's on the agent doing the change.
145+
146+
If `../agent-friendly-action/` isn't present locally, flag it; never silently skip the propagation. Both repos are siblings under the same `personal/` workspace.
147+
133148
## Adding a signal
134149

135150
1. New file at `lib/scoring/signals/<kebab-id>.ts` implementing `Signal` (including `improveSuggestion`).
136151
2. Import and add to the `SIGNALS` array in `lib/scoring/signals/index.ts`.
137152
3. Add a weight entry to **every** model in `lib/scoring/weights.ts` — missing weights default to 0, decide deliberately.
138153
4. Re-score: `bun run seed` is idempotent.
154+
5. **Mirror to the action** (per "Sibling repos" above): copy the new signal file into `../agent-friendly-action/src/scoring/signals/`, add the import + array entry to its `signals/index.ts`, copy the weights changes to its `weights.ts`, and log the addition in `../agent-friendly-action/CHANGELOG.md` under "Unreleased".
139155

140156
## Adding a model
141157

142158
1. Add a `ModelProfile` to `MODELS` in `lib/scoring/weights.ts` — weights for every signal.
143159
2. Appears automatically in the leaderboard model pills and repo-page suggestions.
160+
3. **Mirror to the action**: copy the weights change into `../agent-friendly-action/src/scoring/weights.ts` and log under "Unreleased" in its `CHANGELOG.md`.
144161

145162
## Adding a host
146163

@@ -180,7 +197,7 @@ Hooks docs: <https://docs.claude.com/en/docs/claude-code/hooks.html>.
180197

181198
- 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.
182199
- SQL: all queries parameterised. No interpolation.
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.
200+
- HTML: React auto-escapes. The only `dangerouslySetInnerHTML` is server-built JSON-LD with `<` escaped to `<` (`app/layout.tsx`, `app/page.tsx`, `app/action/page.tsx`, `app/methodology/page.tsx`, `app/repo/[id]/page.tsx`, `app/package/[registry]/[name]/page.tsx`); never feed user-controlled strings into it.
184201
- Local-path mode reads files; never writes outside `data/` and the clone workspace passed to `shallowClone`.
185202
- 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.
186203

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ CLAUDE.md Pointer → AGENTS.md
166166
LICENSE MIT
167167
```
168168

169+
## Companion: PR-diff GitHub Action
170+
171+
[`hsnice16/agent-friendly-action`](https://github.com/hsnice16/agent-friendly-action) runs the same scorer inside your CI and posts a per-PR score-delta comment — _"this PR drops your Claude Code score by 4.1 points because it removed CI config."_ Opt-in via an `AGENTS_BADGE_TOKEN` secret; falls through silently when unset. Each repo detail page on the dashboard ships a copy-paste workflow snippet under "Catch score regressions on every PR".
172+
169173
## Roadmap (high-level)
170174

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

app/about/page.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import { ArrowUpRight } from "@phosphor-icons/react/dist/ssr";
12
import type { Metadata } from "next";
23
import Link from "next/link";
3-
44
import { Panel, PanelHeading } from "@/components/Panel";
55
import { APP_NAME, REPO_URL } from "@/lib/version";
66

@@ -30,9 +30,9 @@ export default function AboutPage() {
3030
target="_blank"
3131
rel="noopener noreferrer"
3232
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"
33+
className="inline-flex items-center gap-0.5 border-b border-dotted border-ink-dim/60 text-ink-dim hover:border-ink-soft hover:text-ink-soft"
3434
>
35-
Himanshu Singh
35+
Himanshu Singh <ArrowUpRight size={11} weight="bold" aria-hidden="true" />
3636
</a>
3737
. Independent project — no affiliation with Anthropic, OpenAI, Google, Cognition, Anysphere, or any of the
3838
agent vendors ranked here.
@@ -83,9 +83,9 @@ export default function AboutPage() {
8383
href={REPO_URL}
8484
target="_blank"
8585
rel="noopener noreferrer"
86-
className="border-b border-dotted border-ink-dim/60 text-ink-dim hover:border-ink-soft hover:text-ink-soft"
86+
className="inline-flex items-center gap-0.5 border-b border-dotted border-ink-dim/60 text-ink-dim hover:border-ink-soft hover:text-ink-soft"
8787
>
88-
source repository
88+
source repository <ArrowUpRight size={11} weight="bold" aria-hidden="true" />
8989
</a>
9090
. If a repo&apos;s score looks wrong, file an issue with a link and the rubric to revisit; if a signal is
9191
missing, propose one.
@@ -103,9 +103,9 @@ export default function AboutPage() {
103103
target="_blank"
104104
rel="noopener noreferrer"
105105
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"
106+
className="inline-flex items-center gap-0.5 border-b border-dotted border-ink-dim/60 text-ink-dim hover:border-ink-soft hover:text-ink-soft"
107107
>
108-
GitHub
108+
GitHub <ArrowUpRight size={11} weight="bold" aria-hidden="true" />
109109
</a>
110110
.
111111
</p>

0 commit comments

Comments
 (0)