From 11f5e2ceaba049874d1cfb9c9caef5f561f0d6ef Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 14:12:14 +0800 Subject: [PATCH 01/31] feat: add scan-stars skill and Rejected Additions register Co-Authored-By: Claude --- .claude/skills/audit-the-list/SKILL.md | 2 +- .claude/skills/review-prs/SKILL.md | 2 +- .claude/skills/scan-stars/SKILL.md | 36 ++++++ .../skills/scan-stars/scripts/scan_stars.py | 117 ++++++++++++++++++ docs/audit-logs.md | 4 + 5 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 .claude/skills/scan-stars/SKILL.md create mode 100644 .claude/skills/scan-stars/scripts/scan_stars.py diff --git a/.claude/skills/audit-the-list/SKILL.md b/.claude/skills/audit-the-list/SKILL.md index 66118c1f..b7b397ea 100644 --- a/.claude/skills/audit-the-list/SKILL.md +++ b/.claude/skills/audit-the-list/SKILL.md @@ -27,7 +27,7 @@ Done when every entry in scope has downloads (or a stated no-signal reason), rep ## 3. Verdicts -Draft a verdict and reason for every entry, restructure before cap: decide Splits, mints, and re-homes first — cutting before restructuring destroys entries — then apply the cap tier by tier, including promotions and demotions between obvious choice and challenger. Ground every reason in the fetched evidence; label anything unverifiable as a judgment call. Where fresh evidence contradicts the standing verdict, say so in the reason instead of silently keeping the seed. +Draft a verdict and reason for every entry, restructure before cap: decide Splits, mints, and re-homes first — cutting before restructuring destroys entries — then apply the cap tier by tier, including promotions and demotions between obvious choice and challenger. Ground every reason in the fetched evidence; label anything unverifiable as a judgment call. Where fresh evidence contradicts the standing verdict, say so in the reason instead of silently keeping the seed. A proposed addition under `docs/audit-logs.md` "Rejected Additions" seeds as drop from that line. ## 4. Review and go diff --git a/.claude/skills/review-prs/SKILL.md b/.claude/skills/review-prs/SKILL.md index f5c3c890..70bb8ba3 100644 --- a/.claude/skills/review-prs/SKILL.md +++ b/.claude/skills/review-prs/SKILL.md @@ -16,7 +16,7 @@ Sort the batch: entry additions continue; anything else (typo fixes, website cha ## 2. Screen -Apply the Automatic Rejection rules that the diff and PR metadata answer without judgment. The recently-closed-duplicate rule needs a lookup: `gh pr list --repo vinta/awesome-python --state closed --search "" --limit 10`. A screened-out PR goes straight to step 4 as a close, with the rule it broke as its reason. +Apply the Automatic Rejection rules that the diff and PR metadata answer without judgment. The recently-closed-duplicate rule needs a lookup: `gh pr list --repo vinta/awesome-python --state closed --search "" --limit 10`; a project under `docs/audit-logs.md` "Rejected Additions" also counts as previously rejected unless the PR brings evidence newer than its line. A screened-out PR goes straight to step 4 as a close, with the rule it broke as its reason. Resolve each survivor's target use case against the current README — a diff's context lines show the base the PR was written on, which may have changed since. A merge conflict rides to the Merge arm, which absorbs it. Done when every surviving PR names its target use case. diff --git a/.claude/skills/scan-stars/SKILL.md b/.claude/skills/scan-stars/SKILL.md new file mode 100644 index 00000000..41b9e0e7 --- /dev/null +++ b/.claude/skills/scan-stars/SKILL.md @@ -0,0 +1,36 @@ +--- +name: scan-stars +description: Scan the maintainer's GitHub stars for README.md addition candidates; incremental by default, `full` rejudges stars judged before. +argument-hint: [full] +disable-model-invocation: true +--- + +# Scan stars + +A star scan turns the maintainer's GitHub stars into proposed additions. Every star the scan sees ends in one place: listed in README.md, screened out in `local/starred-scan.tsv`, or rejected under `docs/audit-logs.md` "Rejected Additions". Judgment belongs to `audit-the-list` and the rules to CONTRIBUTING.md; this skill only sources candidates and records outcomes. + +## 1. Scan + +Run `uv run python .claude/skills/scan-stars/scripts/scan_stars.py`, adding `--full` when the argument is `full`. With no ledger yet, a plain run already covers every star. Print the drop counts from stderr. Done when the candidate TSV is in hand. + +## 2. Screen + +Judge each candidate from its name, description, topics, and language against CONTRIBUTING Quality Requirement 1 (Serves Python Developers), and name the current use case it would compete in. The screen is loose: drop only what plainly fails, and pass anything uncertain on, since `audit-the-list` is the real judge. In a full scan, read the `prior` column as context and overturn a rejection only on new evidence. + +Append each screen-out to `local/starred-scan.tsv` as it is decided, one `repoyyyy-mm-ddreason` row (create the file with header `repo date reason`), so an interrupted run keeps its work. The file is append-only; the script reads the last row per repo. A survivor no current use case fits is a structure question: carry it to review with its evidence. Done when every candidate is a ledger row, holds a target use case, or is a structure question. + +## 3. Judge + +Group survivors by target use case. Per group, invoke `audit-the-list` with: "Judge proposed entries for the
use case. Evidence and Verdicts steps only; report the verdicts back. No preview page, no README changes, no commits." Done when every survivor holds an add or drop verdict with a reason, and each add at cap names the entry it displaces. + +## 4. Review + +Run `preview-verdicts` over all groups: survivors as `add` or `drop` rows, displaced entries as `drop`, structure questions noted on their group, and any `prior` verdict quoted in the row's reason. Done when the maintainer's feedback is processed and they gave the go. + +## 5. Record + +- **Added**: follow `audit-the-list` step 5 for the README change, one commit per entry. +- **Rejected**: a candidate that reached review and was not added gets one line under "Rejected Additions": `- owner/repo -- yyyy-mm-dd, /month (): .`, replacing its earlier line. +- **Parked**: a structure question the maintainer leaves open gets no record, so it resurfaces next run. + +Done when every candidate from step 1 is listed in README.md, a ledger row, a Rejected Additions line, or parked by the maintainer. diff --git a/.claude/skills/scan-stars/scripts/scan_stars.py b/.claude/skills/scan-stars/scripts/scan_stars.py new file mode 100644 index 00000000..f6c10c7a --- /dev/null +++ b/.claude/skills/scan-stars/scripts/scan_stars.py @@ -0,0 +1,117 @@ +"""List the maintainer's GitHub stars that could be README.md candidates. + +Drops stars that fail a check needing no judgment: already listed, own repo, +archived, no push in 12 months, or created under a month ago. These drops are +recomputed every run, so a repo that becomes active again resurfaces. An +incremental run also drops stars already judged: model screen-outs in +local/starred-scan.tsv and maintainer rejections under docs/audit-logs.md +"Rejected Additions". `--full` keeps them and shows the earlier verdict in the +`prior` column. Prints survivors as TSV on stdout, drop counts on stderr. +""" + +import argparse +import json +import re +import subprocess +import sys +from collections import Counter +from datetime import UTC, datetime, timedelta +from pathlib import Path +from typing import TypedDict + +ROOT = Path(__file__).resolve().parents[4] +sys.path.insert(0, str(ROOT / "website")) + +from readme_parser import parse_readme + +LEDGER = ROOT / "local" / "starred-scan.tsv" +REGISTER = ROOT / "docs" / "audit-logs.md" +GITHUB_REPO_RE = re.compile(r"^https://github\.com/([^/#?]+/[^/#?]+)") +REJECTED_LINE_RE = re.compile(r"^- (\S+) -- (.+)$") + + +class Owner(TypedDict): + login: str + + +class Star(TypedDict): + full_name: str + owner: Owner + archived: bool + pushed_at: str + created_at: str + language: str | None + stargazers_count: int + topics: list[str] + description: str | None + + +def gh(*args: str) -> str: + return subprocess.run(["gh", *args], capture_output=True, text=True, check=True).stdout + + +def listed_repos() -> set[str]: + repos = set() + for group in parse_readme((ROOT / "README.md").read_text()): + for category in group["categories"]: + for link in [*category["entries"], *(sub for entry in category["entries"] for sub in entry["also_see"])]: + if match := GITHUB_REPO_RE.match(link["url"]): + repos.add(match.group(1).removesuffix(".git").lower()) + return repos + + +def prior_verdicts() -> dict[str, str]: + """Repo -> earlier verdict. The ledger is append-only, so its last row per repo wins; a maintainer rejection outranks both.""" + prior = {} + if LEDGER.exists(): + for line in LEDGER.read_text().splitlines()[1:]: + repo, date, reason = line.split("\t", 2) + prior[repo.lower()] = f"screened out {date}: {reason}" + register = REGISTER.read_text().splitlines() + start = register.index("## Rejected Additions") + for line in register[start + 1 :]: + if line.startswith("## "): + break + if match := REJECTED_LINE_RE.match(line): + prior[match.group(1).lower()] = f"rejected {match.group(2)}" + return prior + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument("--full", action="store_true", help="rejudge stars already screened out or rejected") + args = parser.parse_args() + + now = datetime.now(UTC) + login = gh("api", "user", "--jq", ".login").strip().lower() + listed = listed_repos() + prior = prior_verdicts() + + stars: list[Star] = [json.loads(line) for line in gh("api", "--paginate", "user/starred?per_page=100", "--jq", ".[]").splitlines()] + dropped = Counter() + print("repo\tlanguage\tstars\tpushed\ttopics\tdescription\tprior") + for star in stars: + repo = star["full_name"].lower() + if repo in listed: + dropped["already listed"] += 1 + elif star["owner"]["login"].lower() == login: + dropped["own repo"] += 1 + elif star["archived"]: + dropped["archived"] += 1 + elif datetime.fromisoformat(star["pushed_at"]) < now - timedelta(days=365): + dropped["no push in 12 months"] += 1 + elif datetime.fromisoformat(star["created_at"]) > now - timedelta(days=30): + dropped["created under a month ago"] += 1 + elif repo in prior and not args.full: + dropped["judged before"] += 1 + else: + description = " ".join((star["description"] or "").split()) + print("\t".join([star["full_name"], star["language"] or "-", str(star["stargazers_count"]), star["pushed_at"][:10], ",".join(star["topics"]), description, prior.get(repo, "")])) + + print(f"{len(stars)} stars; {len(stars) - dropped.total()} candidates", file=sys.stderr) + for reason, count in dropped.most_common(): + print(f" dropped {count}: {reason}", file=sys.stderr) + + +if __name__ == "__main__": + main() diff --git a/docs/audit-logs.md b/docs/audit-logs.md index ae95952e..ad525f29 100644 --- a/docs/audit-logs.md +++ b/docs/audit-logs.md @@ -67,6 +67,10 @@ These entries sit past the 12-month activity requirement without an override. Ea - schedule -- kept 2026-08-16, recorded 2026-10-02. Last commit 2024-05-25. - sortedcontainers +## Rejected Additions + +A proposed entry the maintainer turned down leaves no commit, so it is recorded here with the evidence at decision time, keyed by its GitHub `owner/repo`. Rejudge one only on new evidence. + ## Last Audited An audit that changes nothing in a section leaves no commit, so its date is recorded here, one line per section, replaced on each re-audit. From 4fd886f0e0d7aea1dd33b9e8161be4eadcf1e7ba Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 14:15:37 +0800 Subject: [PATCH 02/31] feat: honor owner/* organization lines in scan_stars prior verdicts Co-Authored-By: Claude --- .claude/skills/scan-stars/scripts/scan_stars.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.claude/skills/scan-stars/scripts/scan_stars.py b/.claude/skills/scan-stars/scripts/scan_stars.py index f6c10c7a..c0b5fc4e 100644 --- a/.claude/skills/scan-stars/scripts/scan_stars.py +++ b/.claude/skills/scan-stars/scripts/scan_stars.py @@ -92,6 +92,7 @@ def main() -> None: print("repo\tlanguage\tstars\tpushed\ttopics\tdescription\tprior") for star in stars: repo = star["full_name"].lower() + verdict = prior.get(repo) or prior.get(f"{star['owner']['login'].lower()}/*") if repo in listed: dropped["already listed"] += 1 elif star["owner"]["login"].lower() == login: @@ -102,11 +103,11 @@ def main() -> None: dropped["no push in 12 months"] += 1 elif datetime.fromisoformat(star["created_at"]) > now - timedelta(days=30): dropped["created under a month ago"] += 1 - elif repo in prior and not args.full: + elif verdict and not args.full: dropped["judged before"] += 1 else: description = " ".join((star["description"] or "").split()) - print("\t".join([star["full_name"], star["language"] or "-", str(star["stargazers_count"]), star["pushed_at"][:10], ",".join(star["topics"]), description, prior.get(repo, "")])) + print("\t".join([star["full_name"], star["language"] or "-", str(star["stargazers_count"]), star["pushed_at"][:10], ",".join(star["topics"]), description, verdict or ""])) print(f"{len(stars)} stars; {len(stars) - dropped.total()} candidates", file=sys.stderr) for reason, count in dropped.most_common(): From 723d0cae6e333bec90c1c397ef2f17999aa489a8 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 14:15:37 +0800 Subject: [PATCH 03/31] docs: record dacite, autoregistry, schedium, dishka, python-dependency-injector, xberg-io rejections Co-Authored-By: Claude --- docs/audit-logs.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/audit-logs.md b/docs/audit-logs.md index ad525f29..299ebaa9 100644 --- a/docs/audit-logs.md +++ b/docs/audit-logs.md @@ -69,7 +69,14 @@ These entries sit past the 12-month activity requirement without an override. Ea ## Rejected Additions -A proposed entry the maintainer turned down leaves no commit, so it is recorded here with the evidence at decision time, keyed by its GitHub `owner/repo`. Rejudge one only on new evidence. +Projects the maintainer decided not to list, with the evidence at decision time, keyed by GitHub `owner/repo` (`owner/*` for a whole organization). PR reviews and star scans check here before proposing a project again. Rejudge one only on new evidence. + +- BrianPugh/autoregistry -- 2026-08-23, 16,758 downloads/month: 77 stars. +- MarcBresson/schedium -- 2026-08-23, 381 downloads/month: repository created 2026-02-05. +- ets-labs/python-dependency-injector -- 2026-08-23, 9,086,069 downloads/month: the Dependency Injection use case was declined, since FastAPI's Depends and pytest fixtures absorb most of the need, leaving a leader with no challenger field. +- konradhalas/dacite -- 2026-08-23, 23,147,569 downloads/month: last push 2025-03-17, fails the activity rule. +- reagento/dishka -- 2026-08-23, 769,893 downloads/month: declined with the Dependency Injection use case. +- xberg-io/* -- 2026-08-16: coordinated multi-entry self-promotion; four planted entries were removed (xberg, liter-llm, tree-sitter-language-pack, html-to-markdown). Reject any project from this organization on sight. ## Last Audited From e9991f823e5c63427164e8e8fc4f3f59617a12e0 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 14:31:07 +0800 Subject: [PATCH 04/31] refactor: rename scan-stars skill to scan-github-stars Co-Authored-By: Claude --- .claude/skills/{scan-stars => scan-github-stars}/SKILL.md | 6 +++--- .../scripts/scan_github_stars.py} | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename .claude/skills/{scan-stars => scan-github-stars}/SKILL.md (89%) rename .claude/skills/{scan-stars/scripts/scan_stars.py => scan-github-stars/scripts/scan_github_stars.py} (100%) diff --git a/.claude/skills/scan-stars/SKILL.md b/.claude/skills/scan-github-stars/SKILL.md similarity index 89% rename from .claude/skills/scan-stars/SKILL.md rename to .claude/skills/scan-github-stars/SKILL.md index 41b9e0e7..bde84129 100644 --- a/.claude/skills/scan-stars/SKILL.md +++ b/.claude/skills/scan-github-stars/SKILL.md @@ -1,17 +1,17 @@ --- -name: scan-stars +name: scan-github-stars description: Scan the maintainer's GitHub stars for README.md addition candidates; incremental by default, `full` rejudges stars judged before. argument-hint: [full] disable-model-invocation: true --- -# Scan stars +# Scan GitHub stars A star scan turns the maintainer's GitHub stars into proposed additions. Every star the scan sees ends in one place: listed in README.md, screened out in `local/starred-scan.tsv`, or rejected under `docs/audit-logs.md` "Rejected Additions". Judgment belongs to `audit-the-list` and the rules to CONTRIBUTING.md; this skill only sources candidates and records outcomes. ## 1. Scan -Run `uv run python .claude/skills/scan-stars/scripts/scan_stars.py`, adding `--full` when the argument is `full`. With no ledger yet, a plain run already covers every star. Print the drop counts from stderr. Done when the candidate TSV is in hand. +Run `uv run python .claude/skills/scan-github-stars/scripts/scan_github_stars.py`, adding `--full` when the argument is `full`. With no ledger yet, a plain run already covers every star. Print the drop counts from stderr. Done when the candidate TSV is in hand. ## 2. Screen diff --git a/.claude/skills/scan-stars/scripts/scan_stars.py b/.claude/skills/scan-github-stars/scripts/scan_github_stars.py similarity index 100% rename from .claude/skills/scan-stars/scripts/scan_stars.py rename to .claude/skills/scan-github-stars/scripts/scan_github_stars.py From 0a634dff0f357eab70536cb2a56fc91990dd09f2 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:16:35 +0800 Subject: [PATCH 05/31] fix: give each review page verdict a single meaning Drop meant three things on the review page: remove a listed entry, leave a candidate out, or park a structure question with no record. Verdicts are now per row kind: keep/remove for listed entries, add/reject for candidates, restructure/park/reject for structure questions, and the feedback JSON carries the same words. The page also gains an optional Source column naming where each row came from. Star scans now judge an unlisted project a reject names as the better pick, seed judgment-call rows as park, and keep any parked row unrecorded. Co-Authored-By: Claude --- .claude/skills/audit-the-list/SKILL.md | 2 +- .claude/skills/preview-verdicts/SKILL.md | 15 +++++--- .claude/skills/preview-verdicts/template.html | 37 ++++++++++++------- .claude/skills/scan-github-stars/SKILL.md | 6 +-- 4 files changed, 37 insertions(+), 23 deletions(-) diff --git a/.claude/skills/audit-the-list/SKILL.md b/.claude/skills/audit-the-list/SKILL.md index b7b397ea..254c57e0 100644 --- a/.claude/skills/audit-the-list/SKILL.md +++ b/.claude/skills/audit-the-list/SKILL.md @@ -27,7 +27,7 @@ Done when every entry in scope has downloads (or a stated no-signal reason), rep ## 3. Verdicts -Draft a verdict and reason for every entry, restructure before cap: decide Splits, mints, and re-homes first — cutting before restructuring destroys entries — then apply the cap tier by tier, including promotions and demotions between obvious choice and challenger. Ground every reason in the fetched evidence; label anything unverifiable as a judgment call. Where fresh evidence contradicts the standing verdict, say so in the reason instead of silently keeping the seed. A proposed addition under `docs/audit-logs.md` "Rejected Additions" seeds as drop from that line. +Draft a verdict and reason for every entry, restructure before cap: decide Splits, mints, and re-homes first — cutting before restructuring destroys entries — then apply the cap tier by tier, including promotions and demotions between obvious choice and challenger. Ground every reason in the fetched evidence; label anything unverifiable as a judgment call. Where fresh evidence contradicts the standing verdict, say so in the reason instead of silently keeping the seed. A proposed addition under `docs/audit-logs.md` "Rejected Additions" seeds as reject from that line. ## 4. Review and go diff --git a/.claude/skills/preview-verdicts/SKILL.md b/.claude/skills/preview-verdicts/SKILL.md index 1c3bf843..ee8dd716 100644 --- a/.claude/skills/preview-verdicts/SKILL.md +++ b/.claude/skills/preview-verdicts/SKILL.md @@ -1,24 +1,29 @@ --- name: preview-verdicts -description: Generate the interactive keep/drop/add verdict preview (HTML page with per-row feedback controls) whenever a prune sweep, batch entry edit, or restructure needs maintainer review before touching README.md — and process the feedback JSON the maintainer pastes back. +description: Generate the interactive keep/remove/add/reject verdict preview (HTML page with per-row feedback controls) whenever a prune sweep, batch entry edit, or restructure needs maintainer review before touching README.md — and process the feedback JSON the maintainer pastes back. --- # Verdict preview -Maintainer review happens through an interactive HTML page: one row per entry with your seeded verdict and reason, Keep/Drop buttons (Add/Drop on proposed new entries) and a reason field for the maintainer, and a **Copy feedback** button that exports only changed or commented rows as JSON. Generate the page, wait for the pasted JSON, then apply it. Entry changes land in README.md only after the review — and only on an explicit go. +Maintainer review happens through an interactive HTML page: one row per entry with your seeded verdict and reason, verdict buttons and a reason field for the maintainer, and a **Copy feedback** button that exports only changed or commented rows as JSON. Generate the page, wait for the pasted JSON, then apply it. Entry changes land in README.md only after the review — and only on an explicit go. ## Generate the preview -1. Build the `DATA` array. A group is `[section, subcategory, rows]`; a row is `[entry, url, downloads, verdict, reason]`. +1. Build the `DATA` array. A group is `[section, subcategory, rows]`; a row is `[entry, url, downloads, verdict, reason]`, plus an optional sixth `source` field. + - `source` says where a row came from when that is not obvious, such as the starred repo behind a scan candidate or an incumbent pulled in during the audit. The page shows a Source column only when a row has one. - `subcategory` may carry a note after ` — ` (rendered muted): use it for proposed splits, re-homes, or anything the maintainer should weigh for the whole group. - `downloads` is PyPI last-month as a comma-formatted string; use `—` when no signal exists (e.g. agent skill packs), `stdlib` for standard-library modules, `fetch failed` when the lookup failed. State the fetch date in the sub-header. - - `verdict` is `keep`, `drop`, or `add`, seeded from the current adjudication or dry-run. `add` marks a proposed new entry; its row gets Add/Drop buttons, where Drop means not added. Show a replacement as two rows: the old entry `drop`, the new entry `add`. + - `verdict` is seeded from the current adjudication or dry-run, and its row kind sets the buttons, so each verdict word names one outcome: + - Listed entry: `keep` or `remove` (taken out of README.md). + - Proposed new entry: `add` or `reject` (not added, logged under "Rejected Additions"). + - Structure question: `restructure` (take the change the reason or group note describes), `park` (no record, so it resurfaces), or `reject` (logged under "Rejected Additions"); seed it `restructure` or `park`. + - Show a replacement as two rows: the old entry `remove`, the new entry `add`. - `reason` is plain language the maintainer reads cold — no invented shorthand. When fresh evidence contradicts the seeded verdict (a big download count on a drop, a dead repo on a keep), say so in that row's reason instead of silently changing the seed. 2. Copy `template.html` (sibling of this file) and replace the placeholders: `__TITLE__` (page title), `__SUB__` (sub-header: scope, seed provenance, fetch date, and the standing instruction to flip/comment then Copy feedback), `__KEY__` (localStorage key), `__DATA__` (the array). `__KEY__` must be unique per review — slug plus date, e.g. `awesome-python-science-2026-09-01` — because saved state under a reused key bleeds a previous review's flips into rows with the same section and entry name. 3. Write the page to `local/awesome-python--preview.html` in the repo root (git-ignored; create the directory if needed), `open` it, and tell the maintainer the path and the return path: flip or comment rows (they highlight yellow), press **Copy feedback**, paste the JSON into the chat. Done when the page is open and the return path is stated. ## Process the pasted feedback -Each JSON row is `{section, subcategory, entry, my_verdict, your_verdict, reason}`. On a row seeded `add`, `your_verdict: "drop"` means do not add it. The maintainer's verdict is final — apply it, never re-argue it. An empty reason means the verdict stands unexplained; that is enough. +Each JSON row is `{section, subcategory, entry, my_verdict, your_verdict, reason}`, with verdict words as defined above. The maintainer's verdict is final — apply it, never re-argue it. An empty reason means the verdict stands unexplained; that is enough. Before executing, surface anything the flips imply that the maintainer has not decided: a use case pushed past its cap, an entry left homeless by a proposed split, a request that is already satisfied (a no-op). Ask, then execute on their go. Done when every pasted row is either applied or surfaced back — none silently dropped. diff --git a/.claude/skills/preview-verdicts/template.html b/.claude/skills/preview-verdicts/template.html index 980fbc7e..1eb3e405 100644 --- a/.claude/skills/preview-verdicts/template.html +++ b/.claude/skills/preview-verdicts/template.html @@ -27,20 +27,24 @@ td.name { white-space: nowrap; font-weight: 600; } td.name a { color: var(--ink); text-decoration: none; border-bottom: 1px solid #c8c4c0; } td.name a:hover { border-bottom-color: var(--ink); } + td.source { font-size: .95rem; color: var(--muted); max-width: 14rem; } td.dl { white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--muted); text-align: right; } td.mine { white-space: nowrap; } .badge { display: inline-block; font-size: .78rem; font-weight: 700; letter-spacing: .03em; padding: .12em .5em; border-radius: 4px; } .badge.keep { color: var(--keep); background: var(--keep-bg); } - .badge.drop { color: var(--drop); background: var(--drop-bg); } - .badge.add { color: var(--add); background: var(--add-bg); } + .badge.remove, .badge.reject { color: var(--drop); background: var(--drop-bg); } + .badge.add, .badge.restructure { color: var(--add); background: var(--add-bg); } + .badge.park { color: var(--muted); background: var(--line); } td.reason { color: #44403c; font-size: .95rem; max-width: 34rem; } td.yours { white-space: nowrap; } .seg { display: inline-flex; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; } .seg button { border: 0; background: #fff; padding: .3rem .8rem; font: inherit; font-size: .88rem; cursor: pointer; color: var(--muted); } .seg button + button { border-left: 1px solid var(--line); } - .seg button.on.k { background: var(--keep); color: #fff; font-weight: 700; } - .seg button.on.a { background: var(--add); color: #fff; font-weight: 700; } - .seg button.on.d { background: var(--drop); color: #fff; font-weight: 700; } + .seg button.on { color: #fff; font-weight: 700; } + .seg button.on.keep { background: var(--keep); } + .seg button.on.add, .seg button.on.restructure { background: var(--add); } + .seg button.on.remove, .seg button.on.reject { background: var(--drop); } + .seg button.on.park { background: var(--muted); } td.fb input { width: 100%; min-width: 14rem; font: inherit; font-size: .92rem; padding: .3rem .5rem; border: 1px solid var(--line); border-radius: 6px; background: #fff; } td.fb input:focus { outline: 2px solid var(--keep); outline-offset: 0; } .bar { position: fixed; bottom: 0; left: 0; right: 0; background: var(--ink); color: #fafaf9; display: flex; align-items: center; gap: 1.4rem; padding: .7rem 2.5rem; font-size: .95rem; } @@ -70,31 +74,34 @@ const KEY = "__KEY__"; let state = {}; try { state = JSON.parse(localStorage.getItem(KEY) || "{}"); } catch (e) {} +// A row's seeded verdict picks its button set, so each verdict word names one outcome. +const CHOICES = { keep: ["keep", "remove"], remove: ["keep", "remove"], add: ["add", "reject"], reject: ["add", "reject"], restructure: ["restructure", "park", "reject"], park: ["restructure", "park", "reject"] }; +const cap = v => v[0].toUpperCase() + v.slice(1); + function rowId(section, name) { return section + "::" + name; } function render() { const app = document.getElementById("app"); let html = "", lastSection = ""; + const hasSource = DATA.some(g => g[2].some(r => r.length > 5)); for (const [section, subcat, rows] of DATA) { if (section !== lastSection) { html += `

${section}

`; lastSection = section; } const parts = subcat.split(" — "); html += `

${parts[0]}${parts[1] ? ` — ${parts[1]}` : ""}

`; - html += ``; - for (const [name, url, dl, mine, reason] of rows) { + html += `
EntryDownloads/moMy verdictMy reasonYoursYour reason (optional)
${hasSource ? "" : ""}`; + for (const [name, url, dl, mine, reason, source] of rows) { const id = rowId(section, name); const s = state[id] || {}; const yours = s.verdict || mine; const changed = yours !== mine || (s.feedback || "").trim() !== ""; html += ` + ${hasSource ? `` : ""} `; @@ -137,14 +144,16 @@ function collect() { } function updateCounts() { - let keeps = 0, adds = 0, drops = 0, changed = 0; + const tally = {}; + let changed = 0; for (const [section, , rows] of DATA) for (const [name, , , mine] of rows) { const s = state[rowId(section, name)] || {}; const yours = s.verdict || mine; - if (yours === "keep") keeps++; else if (yours === "add") adds++; else drops++; + tally[yours] = (tally[yours] || 0) + 1; if (yours !== mine) changed++; } - document.getElementById("counts").innerHTML = `${keeps} keep · ${drops} drop · ${adds} add  |  ${changed} verdicts flipped`; + const counts = Object.entries(tally).map(([v, n]) => `${n} ${v}`).join(" · "); + document.getElementById("counts").innerHTML = `${counts}  |  ${changed} verdicts flipped`; } function copyFeedback() { diff --git a/.claude/skills/scan-github-stars/SKILL.md b/.claude/skills/scan-github-stars/SKILL.md index bde84129..5ef612c3 100644 --- a/.claude/skills/scan-github-stars/SKILL.md +++ b/.claude/skills/scan-github-stars/SKILL.md @@ -21,16 +21,16 @@ Append each screen-out to `local/starred-scan.tsv` as it is decided, one `repo for the
use case. Evidence and Verdicts steps only; report the verdicts back. No preview page, no README changes, no commits." Done when every survivor holds an add or drop verdict with a reason, and each add at cap names the entry it displaces. +Group survivors by target use case. Per group, invoke `audit-the-list` with: "Judge proposed entries for the
use case. Evidence and Verdicts steps only; report the verdicts back. No preview page, no README changes, no commits." A reject whose reason names an unlisted project as the better pick turns that project into a candidate too: judge it in the same group and mark its source as found in the audit, not starred. Done when every survivor holds an add or reject verdict with a reason, and each add at cap names the entry it displaces. ## 4. Review -Run `preview-verdicts` over all groups: survivors as `add` or `drop` rows, displaced entries as `drop`, structure questions noted on their group, and any `prior` verdict quoted in the row's reason. Done when the maintainer's feedback is processed and they gave the go. +Run `preview-verdicts` over all groups: survivors as `add` or `reject` rows, displaced entries as `remove`, structure questions as `park` or `restructure` rows, and any `prior` verdict quoted in the row's reason. Seed `park` on any row whose verdict rests on a judgment call, except an add where only the tier is in doubt, so the page holds only settled calls. Done when the maintainer's feedback is processed and they gave the go. ## 5. Record - **Added**: follow `audit-the-list` step 5 for the README change, one commit per entry. - **Rejected**: a candidate that reached review and was not added gets one line under "Rejected Additions": `- owner/repo -- yyyy-mm-dd, /month (): .`, replacing its earlier line. -- **Parked**: a structure question the maintainer leaves open gets no record, so it resurfaces next run. +- **Parked**: a row the maintainer parks gets no record, so it resurfaces next run. Done when every candidate from step 1 is listed in README.md, a ledger row, a Rejected Additions line, or parked by the maintainer. From 51ccfccf3b79aef6a3c846ca9b1d3d9ec09710e6 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:21:50 +0800 Subject: [PATCH 06/31] docs: record 82 star-scan rejections Each line keeps the ClickPy downloads and the reason at decision time, so later PR reviews and star scans don't propose these projects again without new evidence. Co-Authored-By: Claude --- docs/audit-logs.md | 82 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/docs/audit-logs.md b/docs/audit-logs.md index 299ebaa9..94d295c3 100644 --- a/docs/audit-logs.md +++ b/docs/audit-logs.md @@ -77,6 +77,88 @@ Projects the maintainer decided not to list, with the evidence at decision time, - konradhalas/dacite -- 2026-08-23, 23,147,569 downloads/month: last push 2025-03-17, fails the activity rule. - reagento/dishka -- 2026-08-23, 769,893 downloads/month: declined with the Dependency Injection use case. - xberg-io/* -- 2026-08-16: coordinated multi-entry self-promotion; four planted entries were removed (xberg, liter-llm, tree-sitter-language-pack, html-to-markdown). Reject any project from this organization on sight. +- AbstractUmbra/audioop -- 2026-10-16, 7,714,737 downloads/month (ClickPy): gradio and discord.py require it on Python 3.13+, so the count is transitive. It is a backport of a removed stdlib module, not an audio tool readers choose. +- alteryx/featuretools -- 2026-10-16, 106,521 downloads/month (ClickPy): Fails Active: last commit 2024-11-13, last release 2024-05-14. +- AnswerDotAI/fastcore -- 2026-10-16, 24,139,424 downloads/month (ClickPy): ghapi requires it, and the jump from 11.5M to 50.9M is pull from that dependency. It is a fastai grab-bag, not a built-in class enhancement. +- anthropics/claude-code-security-review -- 2026-10-16, no PyPI download signal: A language-agnostic GitHub Action with no releases and no commits since 2026-02-11. Not Python work. +- apple-aiml-research/ml-stable-diffusion -- 2026-10-16, no PyPI download signal: Fails Active: the last human commit is 2025-07-03, and the 2026 commit is a bot. It is a Core ML/Swift path, not a Python generation library. +- arrobalytics/django-ledger -- 2026-10-16, 17,102 downloads/month (ClickPy): An accounting engine, not an ERP suite. Small demand, no Development Status classifier, and no production case studies found. +- asdf-vm/asdf -- 2026-10-16, no PyPI download signal: The tool users are leaving for mise, with the 0.16 Go rewrite cited as the trigger. PyPI "asdf" is an unrelated astronomy package. +- AUTOMATIC1111/stable-diffusion-webui -- 2026-10-16, no PyPI download signal: Fails Active: the last commit on the default branch is 2024-07-27, and its pushed_at date doesn't reflect code changes. +- binaryornot/binaryornot -- 2026-10-16, 13,794,027 downloads/month (ClickPy): cookiecutter requires it, which accounts for about half the count. It does a narrow job, and the use case is at cap. +- bisohns/search-engine-parser -- 2026-10-16, 22,138 downloads/month (ClickPy): Last release 2022-11, and it pins lxml<5. It scrapes search results pages, not page content. +- bookieio/breadability -- 2026-10-16, 106,712 downloads/month (ClickPy): sumy pulls in almost all of the count. Its first release since 2014 lists Python 3.6 classifiers. +- boson-ai/higgs-audio -- 2026-10-16, 416 downloads/month (ClickPy): Two releases, both on 2025-10-03, and the PyPI homepage is a placeholder. v3 moved to Hugging Face plus an API, so nothing pip-installable is maintained. +- caesar0301/treelib -- 2026-10-16, 1,532,895 downloads/month (ClickPy): anytree (6.0M) is the bigger tree library at 4x the downloads, so treelib is not the obvious choice. +- chibisov/drf-extensions -- 2026-10-16, 2,067,903 downloads/month (ClickPy): Last release declares Django<6.0, and it is a DRF add-on, not an API framework. +- cknd/stackprinter -- 2026-10-16, 334,597 downloads/month (ClickPy): Flat downloads, and one release after a two-year gap. No sign of a challenger trajectory. +- clips/pattern -- 2026-10-16, no PyPI download signal: The code ended in 2018, and the 2026 commit is a README edit. PyPI "pattern" is now an unrelated package. Previously removed 2026-03-21 (f52c85a) as unmaintained, and nothing has changed since. +- closeio/ciso8601 -- 2026-10-16, 6,373,074 downloads/month (ClickPy): The use case is full. Its own docs tell users on Python 3.11+ to use datetime.fromisoformat unless they need the speed, so it is a narrow speed-up, not a general datetime library. +- codelucas/newspaper -- 2026-10-16, 468,795 downloads/month (ClickPy): The 2026-03-21 removal (1d09426, unmaintained) still holds: last release was 2018-09, and the 2026 push came with no release. +- coleifer/unqlite-python -- 2026-10-16, 11,386 downloads/month (ClickPy): It binds an embedded database rather than being a server driver, and has negligible demand in either home. +- coleifer/walrus -- 2026-10-16, 182,584 downloads/month (ClickPy): A utility layer over redis-py, not a driver, at under 0.1% of redis's 204M downloads. +- crccheck/django-object-actions -- 2026-10-16, 2,366,676 downloads/month (ClickPy): An add-on for Django admin buttons, not an admin panel. The source of its download count is unknown. +- davidhalter/jedi -- 2026-10-16, 102,370,894 downloads/month (ClickPy): ipython requires it, and its count almost exactly matches ipython's 102.6M. Its job is editor and REPL autocompletion, which the list dropped along with the Editor Plugins section (c87fdac). +- DerwenAI/pytextrank -- 2026-10-16, 82,707 downloads/month (ClickPy): Fails Active: last commit 2024-05-21, last release 2024-02-21. +- django-haystack/celery-haystack -- 2026-10-16, 1,919 downloads/month (ClickPy): Last release 2015-12. +- django-parler/django-parler -- 2026-10-16, 160,493 downloads/month (ClickPy): django-modeltranslation (826,853) has 5x its downloads, so it is not the obvious choice for Django model translation. +- doableware/djongo -- 2026-10-16, 57,392 downloads/month (ClickPy): Its latest release (1.3.7, 2024-11) pins django<=3.1.12, so it can't be installed with any supported Django. django-mongodb-backend already does this job. +- Doist/bitmapist -- 2026-10-16, 7,385 downloads/month (ClickPy): A Redis bitmap analytics library, not a driver, with negligible demand. Its metadata caps Python below 3.14 and redis below 6.0. +- dpath-maintainers/dpath-python -- 2026-10-16, 8,884,938 downloads/month (ClickPy): checkov and airbyte-cdk pull it in, leaving about 3.5M independent, below the section's floor (python-box, 4.9M). Last release 2024-06. +- dpkp/kafka-python -- 2026-10-16, 17,148,353 downloads/month (ClickPy): It was removed as unmaintained on 2026-03-21 (e8d3d29), but it was still releasing then and has shipped 3.0.0 through 3.0.11 since (June to August 2026), so that reason no longer holds. It is held back by tier: confluent-kafka (41.5M) is the default for new projects, and kafka-python is the pure-Python fallback rather than a successor. +- dwolfhub/zxcvbn-python -- 2026-10-16, 4,673,093 downloads/month (ClickPy): Password-strength estimation is not cryptography, and there is no use case for passwords. It also fails Active: last commit on master was 2025-10-06. +- explorerhq/sql-explorer -- 2026-10-16, 213,897 downloads/month (ClickPy): A SQL reporting tool, not an admin panel, and below the smallest incumbent (django-grappelli, 281,247). +- frostming/marko -- 2026-10-16, 5,798,780 downloads/month (ClickPy): The obvious tier (markdown-it-py, markdown, mistune) is full. Its growth roughly tracks the general ClickPy inflation, and no source shows it replacing any of the three. +- ggml-org/whisper.cpp -- 2026-10-16, 734,136 downloads/month (ClickPy): Python uses it through the separate third-party absadiki/pywhispercpp (349 stars). It does faster-whisper's job (12.1M) with no sign of overtaking it. The download count is unexplained for 349 stars. +- gitleaks/gitleaks -- 2026-10-16, no PyPI download signal: Secret Scanning was minted with betterleaks alone. gitleaks is a language-agnostic Go binary with slowing activity (last release 2026-03-21). +- hhatto/autopep8 -- 2026-10-16, 7,132,827 downloads/month (ClickPy): The use case holds 6 entries under a cap exception, and none is weaker (flake8 39.6M, bandit 24.5M). Last release was 2025-01, and the 2026 commits are dependabot only. +- html5lib/html5lib-python -- 2026-10-16, 26,055,801 downloads/month (ClickPy): The 2026-03-21 removal (7f21136, no release since 2019) still holds: last release 1.1 in 2020-06. The count comes from 3,281 dependents rather than people picking it, and justhtml already covers pure-Python HTML5 parsing. +- huggingface/speech-to-speech -- 2026-10-16, 2,714 downloads/month (ClickPy): An end-to-end voice pipeline app, not an ASR/TTS library, and far below the smallest Speech entry (funasr, 297,003). +- jazzband/django-pipeline -- 2026-10-16, 222,640 downloads/month (ClickPy): The 2026-03-21 removal (6b59080) gave overlap with django-compressor as the reason, which still holds: django-compressor has 11x its downloads. +- jundot/omlx -- 2026-10-16, no PyPI download signal: A macOS menu-bar app (repo created 2026-02-13), not a library. mlx-lm already covers Apple Silicon. +- jupyter/docker-stacks -- 2026-10-16, no PyPI download signal: Container images that package notebook (already listed), not an interpreter. +- kaifcodec/user-scanner -- 2026-10-16, 16,772 downloads/month (ClickPy): The use case is at cap. sherlock-project does the same username OSINT job at 4x the downloads. Repo created 2025-10. +- keleshev/schema -- 2026-10-16, 19,658,077 downloads/month (ClickPy): Removed as unmaintained on 2026-03-21 (e8d3d29), and activity has not resumed: the last release was 0.7.8 in 2025-10, with only a push since. It is classified Alpha and is not a successor to pydantic or jsonschema. +- kellyjonbrazil/jc -- 2026-10-16, 626,452 downloads/month (ClickPy): Parser is at cap (floor: parsy, 3.96M). jc does a different job (CLI output to JSON) and has no entry to replace. +- lexiforest/curl_cffi -- 2026-10-16, 31,930,921 downloads/month (ClickPy): About 17.4M of this is pulled in by yfinance, leaving roughly 14M of its own demand. HTTP Clients General is at cap, and web sources frame it as a TLS-fingerprint impersonation tool for getting past anti-bot blocks, not as a successor to requests or httpx2. No use case covers impersonation. +- LPgenerator/django-db-mailer -- 2026-10-16, 1,143 downloads/month (ClickPy): Last release 2018-10. +- mahmoud/glom -- 2026-10-16, 23,112,427 downloads/month (ClickPy): semgrep requires it, leaving about 3.5M independent. It is a transformer for nested data rather than a built-in class enhancement. +- mailgun/flanker -- 2026-10-16, 36,887 downloads/month (ClickPy): The 2026-03-21 removal (7f21136, abandoned by Mailgun) still holds: last release 2019-12. It parses mail rather than sending it. +- matthewwithanm/django-imagekit -- 2026-10-16, 380,436 downloads/month (ClickPy): Django-specific and below General's floor. Django thumbnailing has no clear leader (sorl-thumbnail 485K, easy-thumbnails 469K). +- matthewwithanm/pilkit -- 2026-10-16, 380,588 downloads/month (ClickPy): Pulled in by django-imagekit (nearly identical counts). Last release 2023-09. +- maxfischer2781/asyncstdlib -- 2026-10-16, 4,288,321 downloads/month (ClickPy): Async I/O already holds 6 entries under a cap exception. This is a different job (async versions of builtins and itertools), and aiostream (3.8M) is an equal peer. +- MemPalace/mempalace -- 2026-10-16, 56,453 downloads/month (ClickPy): Data Layer is at cap. Agent memory is mem0's job (2.0M), so there is no one-in-one-out case. Its April 2026 launch coverage centred on disputed benchmarks (the 100% LongMemEval claim was pulled), it is classified Beta, and its popularity is driven by stars (59.6k stars vs 56k downloads). +- mewwts/addict -- 2026-10-16, 6,120,693 downloads/month (ClickPy): Fails Active: last commit 2021-01, last release 2020-11. python-box, already listed, does the same job. +- microsoft/bocpy -- 2026-10-16, 9,933 downloads/month (ClickPy): Created 2026-02, classified Beta, 201 stars. No adoption-trajectory evidence. +- mongodb/motor -- 2026-10-16, 9,226,799 downloads/month (ClickPy): Deprecated in favor of the PyMongo Async API (2025-05-14) and end-of-life since 2026-05-14. Its last release was 3.7.1 in 2025-05, and pymongo is listed. The earlier removal (d9bba73, 2026-01-16, "unmaintained") still holds. +- mpdavis/python-jose -- 2026-10-16, 32,386,854 downloads/month (ClickPy): The 2026-03-21 removal (f50bd8f, superseded) still holds: FastAPI's JWT tutorial now uses PyJWT, and several dependents migrated away after CVE-2024-33663. No release since 2025-05. +- myusuf3/delorean -- 2026-10-16, 107,732 downloads/month (ClickPy): Removed 2024-02-23 (8524f28). 2.0.0 (2026-08) is its first release since 2018, and that day's commits are docs and CI only. It is Beta, has little demand, and the use case is full. +- noripyt/django-cachalot -- 2026-10-16, 244,358 downloads/month (ClickPy): Does the same job as django-cacheops (listed), which has 8x its downloads. +- oobabooga/textgen -- 2026-10-16, no PyPI download signal: A desktop app, not a pip library. PyPI "textgen" is an unrelated package. +- opensanctions/countrynames -- 2026-10-16, 15,360 downloads/month (ClickPy): Narrow job. pycountry (32.2M, unlisted) is the obvious country-data library. +- osantana/prettyconf -- 2026-10-16, 29,957 downloads/month (ClickPy): The use case is full at 5 entries, and prettyconf has about 0.6% of the downloads of dynaconf, the smallest entry. +- pydata/numexpr -- 2026-10-16, 12,883,844 downloads/month (ClickPy): Healthy (2.14.2 released 2026-07), but Core already holds numpy, scipy, and numba with far more demand. numexpr is an older accelerator, not a successor to any of them. +- python-excel/xlrd -- 2026-10-16, 70,465,563 downloads/month (ClickPy): Removed 2026-01-16 (d9bba73) as archived, but the repo was never archived. Releases have not resumed since 2.0.2 (2025-06), its own tagline says to use openpyxl where possible, it reads only legacy .xls, and python-calamine (7.7M) is the recommended replacement. Most of the count is direct demand. +- rajatim/zhtw -- 2026-10-16, 719 downloads/month (ClickPy): 14 stars, created 2025-12. It covers a narrower part of OpenCC's job. +- rushter/MLAlgorithms -- 2026-10-16, no PyPI download signal: Educational code, not on PyPI. thealgorithms already covers this. +- s3tools/s3cmd -- 2026-10-16, 1,243,432 downloads/month (ClickPy): The 2026-03-21 removal (e8d3d29) still holds: last release 2023-12, and it crosses the 12-month activity line on 2026-10-22. awscli and boto3 cover the job. +- saresend/KSUID -- 2026-10-16, 74,743 downloads/month (ClickPy): Fails Active: last commit 2018-11, last release 2017. svix-ksuid (1.0M) is the bigger KSUID library. +- shibing624/text2vec -- 2026-10-16, 2,291 downloads/month (ClickPy): sentence-transformers (listed) covers this, and there is no independent demand. +- smartcrop/smartcrop.py -- 2026-10-16, 29,956 downloads/month (ClickPy): A niche content-aware cropping job at 30K, and General is at cap (floor: pyvips, 867,739). +- SmileyChris/easy-thumbnails -- 2026-10-16, 469,327 downloads/month (ClickPy): Django-specific and below General's floor, with no lead over sorl-thumbnail. Last release 2025-08. +- ssut/py-googletrans -- 2026-10-16, 1,941,718 downloads/month (ClickPy): Fails Active: last commit 2025-04. It is an unofficial Google Translate scraper (machine translation, not i18n). +- TeamHG-Memex/eli5 -- 2026-10-16, 84,428 downloads/month (ClickPy): Fails Active: the maintained fork eli5-org/eli5 last committed on 2025-04-20, and recent commits to the original repo only delete workflow files. +- TheTom/turboquant_plus -- 2026-10-16, no PyPI download signal: A research repo for KV-cache quantization. Every commit since 2026-06-12 is a README edit, and the latest says the work was merged upstream into mlx-swift-lm. Nothing pip-installable. +- thumbor/libthumbor -- 2026-10-16, 66,538 downloads/month (ClickPy): A companion to the listed thumbor. Last release 2022-03, with only dependabot commits since. +- THUwangcy/ReChorus -- 2026-10-16, no PyPI download signal: An academic research framework with 648 stars, not on PyPI. +- tyiannak/pyAudioAnalysis -- 2026-10-16, 13,577 downloads/month (ClickPy): Removed 2026-03-21 (e8d3d29) as unmaintained, and that still holds: last release 2022-02, with only README edits since. +- uploadcare/pillow-simd -- 2026-10-16, 66,174 downloads/month (ClickPy): A fork of the listed pillow with 0.01% of its downloads, and General is at cap. +- wroberts/pytimeparse -- 2026-10-16, 23,637,352 downloads/month (ClickPy): Its count matches agate's (20.8M), which dbt-core pulls in, so very little of it is people choosing pytimeparse. 1.1.9 is its first release since 2018 and is classified Beta. The use case is full. +- x-hw/amazing-qr -- 2026-10-16, 812 downloads/month (ClickPy): Its 10.8k stars don't show up as installs. It pins Pillow<12, while qrcode (28.7M) holds the use case. +- xhtml2pdf/xhtml2pdf -- 2026-10-16, 3,813,456 downloads/month (ClickPy): It was removed in 2016 (a936fd1) as "deprecated in favor of WeasyPrint", which is no longer true: it shipped 0.2.22–0.2.24 in 2026-10. It still fails the tier bar, since the web calls WeasyPrint the default (32.5M) and describes xhtml2pdf as having limited CSS. It is an older alternative, not a successor. +- Yelp/detect-secrets -- 2026-10-16, 9,698,855 downloads/month (ClickPy): Weak maintenance: last release 2024-05, last code commit 2025-01, and only a CI commit in 2026. Demand rose 6.6x with no explained cause. +- youssofal/MTPLX -- 2026-10-16, 7,276 downloads/month (ClickPy): Narrow: its own summary is "Native MTP speculative decoding for Qwen3-Next on Apple Silicon". Repo created 2026-05-02, and it hard-requires mlx-lm, which is already listed, so it is an add-on rather than a separate pick. +- ytdl-org/youtube-dl -- 2026-10-16, 164,180 downloads/month (ClickPy): The 2026-03-21 removal (f50bd8f, replaced by yt-dlp) still holds: no release since 2021.12.17, commits stopped 2025-11, and downloads are falling. ## Last Audited From 71bd580429666d45bf68e2c976faae7b9a7b6e5b Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:23:29 +0800 Subject: [PATCH 07/31] refactor: split LLM Inference and Serving into Local LLM Inference and LLM Serving Local runners (ollama, llama-cpp-python, mlx-lm) and production serving engines (vllm, sglang) answer different needs, and one use case could not hold both at the cap. The old page redirects to LLM Serving. Co-Authored-By: Claude --- README.md | 5 +++-- website/data/redirects.json | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 73a63a73..0ad0d4c6 100644 --- a/README.md +++ b/README.md @@ -168,10 +168,11 @@ _Libraries for building AI applications, LLM integrations, and autonomous agents - Pre-trained Models - [transformers](https://github.com/huggingface/transformers) - The model-definition framework for pretrained models in text, computer vision, audio, video, and multimodal tasks, for inference and training. - [sentence-transformers](https://github.com/huggingface/sentence-transformers) - Compute embeddings, run retrieval, and rerank results with pretrained and fine-tuned models. -- LLM Inference and Serving +- Local LLM Inference + - [mlx-lm](https://github.com/ml-explore/mlx-lm) - Run and fine-tune large language models on Apple Silicon with MLX. +- LLM Serving - [vllm](https://github.com/vllm-project/vllm) - A high-throughput and memory-efficient inference and serving engine for LLMs. - [sglang](https://github.com/sgl-project/sglang) - A high-performance serving framework for large language models and multimodal models. - - [mlx-lm](https://github.com/ml-explore/mlx-lm) - Run and fine-tune large language models on Apple Silicon with MLX. - LLM Gateways - [litellm](https://github.com/BerriAI/litellm) - Call 100+ LLMs using OpenAI format. - Image and Video Generation diff --git a/website/data/redirects.json b/website/data/redirects.json index 51e5593b..d5dc47fd 100644 --- a/website/data/redirects.json +++ b/website/data/redirects.json @@ -1,5 +1,6 @@ { "/categories/": "/", + "/categories/ai-and-agents/llm-inference-and-serving/": "/categories/ai-and-agents/llm-serving/", "/categories/ai-and-agents/pre-trained-models-and-inference/": "/categories/ai-and-agents/pre-trained-models/", "/categories/cli-development/cli-development/": "/categories/cli-development/", "/categories/cli-tools/productivity-tools/": "/categories/cli-tools/", From 532f05e4f61b38df23a9df7ee63e3c04a47c9729 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:25:09 +0800 Subject: [PATCH 08/31] feat: add ollama to AI and Agents > Local LLM Inference Co-Authored-By: Claude --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0ad0d4c6..9855be08 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,7 @@ _Libraries for building AI applications, LLM integrations, and autonomous agents - [transformers](https://github.com/huggingface/transformers) - The model-definition framework for pretrained models in text, computer vision, audio, video, and multimodal tasks, for inference and training. - [sentence-transformers](https://github.com/huggingface/sentence-transformers) - Compute embeddings, run retrieval, and rerank results with pretrained and fine-tuned models. - Local LLM Inference + - [ollama](https://github.com/ollama/ollama-python) - Python client for Ollama, which downloads and runs open-weight LLMs locally. - [mlx-lm](https://github.com/ml-explore/mlx-lm) - Run and fine-tune large language models on Apple Silicon with MLX. - LLM Serving - [vllm](https://github.com/vllm-project/vllm) - A high-throughput and memory-efficient inference and serving engine for LLMs. From 72469f9d7db0856edbef8cd2074712e9d92e1bbe Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:25:14 +0800 Subject: [PATCH 09/31] feat: add llama-cpp-python to AI and Agents > Local LLM Inference Co-Authored-By: Claude --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9855be08..065d7b0b 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,7 @@ _Libraries for building AI applications, LLM integrations, and autonomous agents - [sentence-transformers](https://github.com/huggingface/sentence-transformers) - Compute embeddings, run retrieval, and rerank results with pretrained and fine-tuned models. - Local LLM Inference - [ollama](https://github.com/ollama/ollama-python) - Python client for Ollama, which downloads and runs open-weight LLMs locally. + - [llama-cpp-python](https://github.com/abetlen/llama-cpp-python) - Python bindings for llama.cpp, for running GGUF models locally. - [mlx-lm](https://github.com/ml-explore/mlx-lm) - Run and fine-tune large language models on Apple Silicon with MLX. - LLM Serving - [vllm](https://github.com/vllm-project/vllm) - A high-throughput and memory-efficient inference and serving engine for LLMs. From 349e0d1aeb9e9fed196f4d19c406eff0e8542899 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:25:19 +0800 Subject: [PATCH 10/31] feat: add imbalanced-learn to Machine Learning > General Co-Authored-By: Claude --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 065d7b0b..40c14308 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,7 @@ _Libraries for Machine Learning. Also see [awesome-machine-learning](https://git - General - [scikit-learn](https://github.com/scikit-learn/scikit-learn) - The most popular Python library for Machine Learning with extensive documentation and community support. + - [imbalanced-learn](https://github.com/scikit-learn-contrib/imbalanced-learn) - Resampling techniques for datasets with imbalanced classes, compatible with scikit-learn. - [pgmpy](https://github.com/pgmpy/pgmpy) - A Python library for causal and probabilistic reasoning with graphical models. - [feature-engine](https://github.com/feature-engine/feature_engine) - sklearn compatible API with the widest toolset for feature engineering and selection. - Gradient Boosting From 369f75e85208c19cd8a9fb72c651cb77fbfec55c Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:25:24 +0800 Subject: [PATCH 11/31] feat: add optuna to Machine Learning > Hyperparameter Optimization Hyperparameter optimization had no use case, and optuna is its obvious choice. Co-Authored-By: Claude --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 40c14308..d2343136 100644 --- a/README.md +++ b/README.md @@ -222,6 +222,8 @@ _Libraries for Machine Learning. Also see [awesome-machine-learning](https://git - [statsforecast](https://github.com/Nixtla/statsforecast) - Fast statistical forecasting models such as ARIMA, ETS, and Theta, compiled with numba. - [sktime](https://github.com/sktime/sktime) - A unified scikit-learn-style framework for forecasting and other time-series learning tasks. - [timesfm](https://github.com/google-research/timesfm) - A pretrained foundation model from Google Research for time-series forecasting, with non-commercial default weights. +- Hyperparameter Optimization + - [optuna](https://github.com/optuna/optuna) - A hyperparameter optimization framework with define-by-run search spaces and pruning of unpromising trials. ### Natural Language Processing From 05d9798280561ade5548e30f0a8d17010162a4c0 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:25:28 +0800 Subject: [PATCH 12/31] feat: add hyperopt to Machine Learning > Hyperparameter Optimization Co-Authored-By: Claude --- README.md | 1 + docs/audit-logs.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index d2343136..3203e6b2 100644 --- a/README.md +++ b/README.md @@ -224,6 +224,7 @@ _Libraries for Machine Learning. Also see [awesome-machine-learning](https://git - [timesfm](https://github.com/google-research/timesfm) - A pretrained foundation model from Google Research for time-series forecasting, with non-commercial default weights. - Hyperparameter Optimization - [optuna](https://github.com/optuna/optuna) - A hyperparameter optimization framework with define-by-run search spaces and pruning of unpromising trials. + - [hyperopt](https://github.com/hyperopt/hyperopt) - Distributed asynchronous hyperparameter optimization with Tree-structured Parzen Estimators. ### Natural Language Processing diff --git a/docs/audit-logs.md b/docs/audit-logs.md index 94d295c3..c61a681c 100644 --- a/docs/audit-logs.md +++ b/docs/audit-logs.md @@ -40,6 +40,7 @@ Entries admitted as challengers without adoption-trajectory evidence, by maintai - seleniumbase -- admitted 2026-08-16 (PR #3284) as a Browser Automation challenger. It wraps selenium, the successor trajectory in the use case belongs to playwright, and its distinct value is its stealth/UC mode. Admitted because that stealth value counts toward Browser Automation. - semantica -- kept 2026-10-01 in the AI and Agents audit as a Data Layer challenger at 16,582 downloads/month on ClickPy, with no adoption-trajectory evidence found. Kept by maintainer decision. - jev-ultrafast -- kept 2026-09-24 as a Web Scraping Frameworks challenger, recorded 2026-10-02. Admitted while the repo was under a month old and not on PyPI, so it has no download signal and no adoption-trajectory evidence; its README calls it an MVP and it needs a hosted TypeSafe API key. Kept by maintainer decision. +- hyperopt -- admitted 2026-10-16 as a Hyperparameter Optimization challenger at 1,793,872 downloads/month on ClickPy. Its 0.3.0 release came after a 4.5-year gap and it has no adoption-trajectory evidence. Admitted by maintainer decision. ### Cap Exceptions From c5bb17ad8bee016e6e8cb50a6d75d577951b85df Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:25:33 +0800 Subject: [PATCH 13/31] feat: add OpenCC to Natural Language Processing > Chinese Co-Authored-By: Claude --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3203e6b2..259c3622 100644 --- a/README.md +++ b/README.md @@ -238,6 +238,7 @@ _Libraries for working with human languages._ - Chinese - [jieba](https://github.com/fxsjy/jieba) - The most popular Chinese text segmentation library. - [pypinyin](https://github.com/mozillazg/python-pinyin) - Convert Chinese hanzi (漢字) to pinyin (拼音). + - [OpenCC](https://github.com/BYVoid/OpenCC) - Conversion between Traditional and Simplified Chinese, with regional variants and phrase-level rules. - [pangu.py](https://github.com/vinta/pangu.py) - Paranoid text spacing. ### Computer Vision From 7e1a9e72dda50db81bf42b0f0258fa25bf79b1a0 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:25:38 +0800 Subject: [PATCH 14/31] feat: add pgvector to Database Drivers > PostgreSQL Co-Authored-By: Claude --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 259c3622..07104f0c 100644 --- a/README.md +++ b/README.md @@ -449,6 +449,7 @@ _Libraries for connecting and operating databases._ - PostgreSQL - [awesome-postgres](https://github.com/dhamaniasad/awesome-postgres) - [psycopg](https://github.com/psycopg/psycopg) - A PostgreSQL adapter for Python, the successor to psycopg2. - [asyncpg](https://github.com/MagicStack/asyncpg) - A fast PostgreSQL Database Client Library for Python/asyncio. + - [pgvector](https://github.com/pgvector/pgvector-python) - pgvector support for Python, adding vector types and similarity search to psycopg, asyncpg, SQLAlchemy, and Django. - SQLite - [awesome-sqlite](https://github.com/planetopendata/awesome-sqlite) - [sqlite3](https://docs.python.org/3/library/sqlite3.html) - (Python standard library) SQLite interface compliant with DB-API 2.0. - [sqlite-utils](https://github.com/simonw/sqlite-utils) - Python CLI utility and library for manipulating SQLite databases. From 4941ace9d3ea463273c7ac25c8681825048dc44a Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:25:43 +0800 Subject: [PATCH 15/31] feat: add apsw to Database Drivers > SQLite Co-Authored-By: Claude --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 07104f0c..07da9e58 100644 --- a/README.md +++ b/README.md @@ -452,6 +452,7 @@ _Libraries for connecting and operating databases._ - [pgvector](https://github.com/pgvector/pgvector-python) - pgvector support for Python, adding vector types and similarity search to psycopg, asyncpg, SQLAlchemy, and Django. - SQLite - [awesome-sqlite](https://github.com/planetopendata/awesome-sqlite) - [sqlite3](https://docs.python.org/3/library/sqlite3.html) - (Python standard library) SQLite interface compliant with DB-API 2.0. + - [apsw](https://github.com/rogerbinns/apsw) - Another Python SQLite Wrapper, exposing the complete SQLite C API. - [sqlite-utils](https://github.com/simonw/sqlite-utils) - Python CLI utility and library for manipulating SQLite databases. - ClickHouse - [clickhouse-connect](https://github.com/ClickHouse/clickhouse-connect) - The official ClickHouse client, with SQLAlchemy and Superset connectors. From 99c7e7805086ee8e68ceec91bed23cf124bbc529 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:25:48 +0800 Subject: [PATCH 16/31] feat: add faiss-cpu to Database > Vector Co-Authored-By: Claude --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 07da9e58..8d978b5f 100644 --- a/README.md +++ b/README.md @@ -474,6 +474,7 @@ _In-process databases usable directly from Python._ - [duckdb](https://github.com/duckdb/duckdb) - An in-process SQL OLAP database management system; optimized for analytics and fast queries, similar to SQLite but for analytical workloads. - [chdb](https://github.com/chdb-io/chdb) - In-process OLAP SQL engine with the full ClickHouse dialect, zero-copy pandas/Arrow interop, and federation to remote ClickHouse clusters via `remoteSecure()`. - Vector + - [faiss-cpu](https://github.com/facebookresearch/faiss) - A library for efficient similarity search and clustering of dense vectors. - [lancedb](https://github.com/lancedb/lancedb) - A developer-friendly embedded retrieval database for multimodal AI. - [chromadb](https://github.com/chroma-core/chroma) - An open-source embedding database for building AI applications with embeddings and semantic search. - [zvec](https://github.com/alibaba/zvec) - A lightweight, in-process vector database that embeds directly into applications. From 90a809d398cd644174376893413f88ce4f811a86 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:25:53 +0800 Subject: [PATCH 17/31] audit: remove dogpile.cache from Caching Removed: dogpile.cache (about 1.9M downloads/month on ClickPy, 2026-10-16, down from 2.67M a year earlier): falling demand, and its slot goes to django-redis in the next commit. Co-Authored-By: Claude --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 8d978b5f..88592e82 100644 --- a/README.md +++ b/README.md @@ -489,7 +489,6 @@ _Libraries for caching data._ - [diskcache](https://github.com/grantjenks/python-diskcache) - SQLite and file backed cache backend, compatible with Django. - [hishel](https://github.com/karpetrosyan/hishel) - RFC 9111 compliant HTTP caching for clients like httpx and requests and servers like FastAPI, with sync and async support. - [django-cacheops](https://github.com/Suor/django-cacheops) - A slick ORM cache with automatic granular event-driven invalidation. -- [dogpile.cache](https://github.com/sqlalchemy/dogpile.cache) - dogpile.cache is a next generation replacement for Beaker made by the same authors. ### Search From f82dbec298544302a0e96e79a7bbdfe85f7df1e3 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:25:58 +0800 Subject: [PATCH 18/31] feat: add django-redis to Caching Co-Authored-By: Claude --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 88592e82..692d3218 100644 --- a/README.md +++ b/README.md @@ -487,6 +487,7 @@ _Libraries for caching data._ - [cachetools](https://github.com/tkem/cachetools) - Extensible memoizing collections and decorators. - [diskcache](https://github.com/grantjenks/python-diskcache) - SQLite and file backed cache backend, compatible with Django. +- [django-redis](https://github.com/jazzband/django-redis) - Full-featured Redis cache backend for Django. - [hishel](https://github.com/karpetrosyan/hishel) - RFC 9111 compliant HTTP caching for clients like httpx and requests and servers like FastAPI, with sync and async support. - [django-cacheops](https://github.com/Suor/django-cacheops) - A slick ORM cache with automatic granular event-driven invalidation. From 187b25bb1d83cb1d566d0286e5bf3d618f0ce54c Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:26:03 +0800 Subject: [PATCH 19/31] audit: remove jev-ultrafast from Web Scraping > Frameworks Removed: jev-ultrafast (no PyPI download signal; not published on PyPI): its README calls it an MVP and it needs a hosted API key, so the challenger slot goes to scrapling in the next commit. This overrides the Challenger Exception recorded 2026-10-02. Co-Authored-By: Claude --- README.md | 1 - docs/audit-logs.md | 1 - website/data/pypi_name_overrides.json | 1 - 3 files changed, 3 deletions(-) diff --git a/README.md b/README.md index 692d3218..3db5071b 100644 --- a/README.md +++ b/README.md @@ -407,7 +407,6 @@ _Libraries to automate web scraping and extract web content._ - [scrapy](https://github.com/scrapy/scrapy) - A fast high-level web crawling and scraping framework. - [crawl4ai](https://github.com/unclecode/crawl4ai) - An open-source, LLM-friendly web crawler that provides lightning-fast, structured data extraction specifically designed for AI agents. - [stagehand](https://github.com/browserbase/stagehand) - A fast and token-efficient browser automation SDK to extract data and perform self-healing actions on web pages. - - [jev-ultrafast](https://github.com/browser-use/jev-ultrafast) - A fast browser agent that picks actions from an indexed table of page elements through TypeSafe's hosted Jev API, using a small LLM only to type text. - Content Extraction - [markdownify](https://github.com/matthewwithanm/python-markdownify) - Convert HTML to Markdown, with customizable tag handling. - [feedparser](https://github.com/kurtmckee/feedparser) - Universal feed parser. diff --git a/docs/audit-logs.md b/docs/audit-logs.md index c61a681c..5aad5c2f 100644 --- a/docs/audit-logs.md +++ b/docs/audit-logs.md @@ -39,7 +39,6 @@ Entries admitted as challengers without adoption-trajectory evidence, by maintai - seleniumbase -- admitted 2026-08-16 (PR #3284) as a Browser Automation challenger. It wraps selenium, the successor trajectory in the use case belongs to playwright, and its distinct value is its stealth/UC mode. Admitted because that stealth value counts toward Browser Automation. - semantica -- kept 2026-10-01 in the AI and Agents audit as a Data Layer challenger at 16,582 downloads/month on ClickPy, with no adoption-trajectory evidence found. Kept by maintainer decision. -- jev-ultrafast -- kept 2026-09-24 as a Web Scraping Frameworks challenger, recorded 2026-10-02. Admitted while the repo was under a month old and not on PyPI, so it has no download signal and no adoption-trajectory evidence; its README calls it an MVP and it needs a hosted TypeSafe API key. Kept by maintainer decision. - hyperopt -- admitted 2026-10-16 as a Hyperparameter Optimization challenger at 1,793,872 downloads/month on ClickPy. Its 0.3.0 release came after a 4.5-year gap and it has no adoption-trajectory evidence. Admitted by maintainer decision. ### Cap Exceptions diff --git a/website/data/pypi_name_overrides.json b/website/data/pypi_name_overrides.json index daf57097..66775d6d 100644 --- a/website/data/pypi_name_overrides.json +++ b/website/data/pypi_name_overrides.json @@ -16,7 +16,6 @@ "google-cloud-python": { "package": null, "reason": "monorepo umbrella; ships as many google-cloud-* packages", "badge": "Multiple on PyPI" }, "graphify": { "package": "graphifyy", "reason": null }, "httpx-url": { "package": null, "reason": "class in the httpx package, not a package" }, - "jev-ultrafast": { "package": null, "reason": "not published on PyPI" }, "jinja": { "package": "jinja2", "reason": "PyPI jinja is Jinja1; current releases publish as jinja2" }, "mem0": { "package": "mem0ai", "reason": null }, "micropython": { "package": null, "reason": "interpreter distributed as firmware builds, not pip" }, From 6084417daf3d6ddd17549b7742d659987a17a4c3 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:26:08 +0800 Subject: [PATCH 20/31] feat: add scrapling to Web Scraping > Frameworks Co-Authored-By: Claude --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3db5071b..cf81ead3 100644 --- a/README.md +++ b/README.md @@ -407,6 +407,7 @@ _Libraries to automate web scraping and extract web content._ - [scrapy](https://github.com/scrapy/scrapy) - A fast high-level web crawling and scraping framework. - [crawl4ai](https://github.com/unclecode/crawl4ai) - An open-source, LLM-friendly web crawler that provides lightning-fast, structured data extraction specifically designed for AI agents. - [stagehand](https://github.com/browserbase/stagehand) - A fast and token-efficient browser automation SDK to extract data and perform self-healing actions on web pages. + - [scrapling](https://github.com/D4Vinci/Scrapling) - An adaptive scraping framework whose selectors relocate elements after page changes, with stealth fetchers and spiders. - Content Extraction - [markdownify](https://github.com/matthewwithanm/python-markdownify) - Convert HTML to Markdown, with customizable tag handling. - [feedparser](https://github.com/kurtmckee/feedparser) - Universal feed parser. From c9095fc74bd723bf4725173d3323f2adfb21861e Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:26:13 +0800 Subject: [PATCH 21/31] feat: add ast-grep-cli to Code Analysis > Refactoring Co-Authored-By: Claude --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index cf81ead3..634d47f3 100644 --- a/README.md +++ b/README.md @@ -654,6 +654,7 @@ _Tools of static analysis, linters and code quality checkers. Also see [awesome- - [bandit](https://github.com/PyCQA/bandit) - A tool designed to find common security issues in Python code. - Refactoring - [rope](https://github.com/python-rope/rope) - Rope is a python refactoring library. + - [ast-grep-cli](https://github.com/ast-grep/ast-grep) - A CLI tool for structural code search, linting, and rewriting based on syntax trees. - Type Checkers - [awesome-python-typing](https://github.com/typeddjango/awesome-python-typing) - [mypy](https://github.com/python/mypy) - A static type checker for Python. - [ty](https://github.com/astral-sh/ty) - An extremely fast Python type checker and language server. From d37b45d03767ac89b6a7dd9034e9b307b8dbc64d Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:26:18 +0800 Subject: [PATCH 22/31] feat: add django-silk to Debugging Tools > Others Co-Authored-By: Claude --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 634d47f3..e168b864 100644 --- a/README.md +++ b/README.md @@ -712,6 +712,7 @@ _Libraries for debugging code._ - [scalene](https://github.com/plasma-umass/scalene) - A high-performance, high-precision CPU, GPU, and memory profiler for Python. - Others - [django-debug-toolbar](https://github.com/django-commons/django-debug-toolbar) - Display various debug information for Django. + - [django-silk](https://github.com/jazzband/django-silk) - Live profiling and inspection of HTTP requests and database queries for Django. - [icecream](https://github.com/gruns/icecream) - Inspect variables, expressions, and program execution with a single, simple function call. - [flask-debugtoolbar](https://github.com/pallets-eco/flask-debugtoolbar) - A port of the django-debug-toolbar to flask. From 9a0040257bbbca70285540016e9a6d41241214e2 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:26:23 +0800 Subject: [PATCH 23/31] feat: add mise to Environment Management Co-Authored-By: Claude --- README.md | 1 + website/data/pypi_name_overrides.json | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index e168b864..5cea146f 100644 --- a/README.md +++ b/README.md @@ -1082,6 +1082,7 @@ _Libraries for Python version and virtual environment management._ - [virtualenv](https://github.com/pypa/virtualenv) - A tool to create isolated Python environments. - [uv](https://github.com/astral-sh/uv) - An extremely fast Python version, package and project manager, written in Rust. - [pyenv](https://github.com/pyenv/pyenv) - Simple Python version management. +- [mise](https://github.com/jdx/mise) - A polyglot tool version manager that installs Python versions and reads .python-version files. ### Package Management diff --git a/website/data/pypi_name_overrides.json b/website/data/pypi_name_overrides.json index 66775d6d..184197e7 100644 --- a/website/data/pypi_name_overrides.json +++ b/website/data/pypi_name_overrides.json @@ -20,6 +20,7 @@ "mem0": { "package": "mem0ai", "reason": null }, "micropython": { "package": null, "reason": "interpreter distributed as firmware builds, not pip" }, "mimetypes": { "package": null, "reason": "stdlib module" }, + "mise": { "package": null, "reason": "not published on PyPI; PyPI mise is an unrelated package" }, "odoo": { "package": null, "reason": "self-hosted suite installed from odoo.com, not pip" }, "pangu-py": { "package": "pangu", "reason": null }, "playwright-python": { "package": "playwright", "reason": null }, From 3e6e5c1932e670132b3303142ed5380da920c192 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:26:28 +0800 Subject: [PATCH 24/31] feat: add pypandoc to File Format Processing > File Conversion Co-Authored-By: Claude --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5cea146f..94197554 100644 --- a/README.md +++ b/README.md @@ -935,6 +935,7 @@ _Libraries for parsing and manipulating specific file formats._ - [tablib](https://github.com/jazzband/tablib) - A module for Tabular Datasets in XLS, CSV, JSON, YAML. - File Conversion - [markitdown](https://github.com/microsoft/markitdown) - Python tool for converting files and office documents to Markdown. + - [pypandoc](https://github.com/JessicaTegner/pypandoc) - A thin wrapper for pandoc, the universal document converter. - [docling](https://github.com/docling-project/docling) - Library for converting documents into structured data. - Excel - [openpyxl](https://openpyxl.readthedocs.io/en/stable/) - A library for reading and writing Excel 2010 xlsx/xlsm/xltx/xltm files. From e011e9a1f1acc8e3920bf9087eb5f1424cd532f1 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:26:33 +0800 Subject: [PATCH 25/31] refactor: split File Manipulation into Paths and File Watching and File Type Detection File type detection is a different job from paths and file watching, and splitting them leaves room for a challenger in each without passing the cap. Co-Authored-By: Claude --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 94197554..b0b8ba8a 100644 --- a/README.md +++ b/README.md @@ -963,11 +963,13 @@ _Libraries for parsing and manipulating specific file formats._ _Libraries for file manipulation._ -- [mimetypes](https://docs.python.org/3/library/mimetypes.html) - (Python standard library) Map filenames to MIME types. -- [pathlib](https://docs.python.org/3/library/pathlib.html) - (Python standard library) A cross-platform, object-oriented path library. -- [watchfiles](https://github.com/samuelcolvin/watchfiles) - Simple, modern and fast file watching and code reload in python. -- [watchdog](https://github.com/gorakhargosh/watchdog) - API and shell utilities to monitor file system events. -- [python-magic](https://github.com/ahupp/python-magic) - A Python interface to the libmagic file type identification library. +- Paths and File Watching + - [pathlib](https://docs.python.org/3/library/pathlib.html) - (Python standard library) A cross-platform, object-oriented path library. + - [watchfiles](https://github.com/samuelcolvin/watchfiles) - Simple, modern and fast file watching and code reload in python. + - [watchdog](https://github.com/gorakhargosh/watchdog) - API and shell utilities to monitor file system events. +- File Type Detection + - [mimetypes](https://docs.python.org/3/library/mimetypes.html) - (Python standard library) Map filenames to MIME types. + - [python-magic](https://github.com/ahupp/python-magic) - A Python interface to the libmagic file type identification library. **Media** From 3f6ed15ba93b3c2682a5f01d4e22058636ce2a29 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:26:39 +0800 Subject: [PATCH 26/31] feat: add magika to File Manipulation > File Type Detection Co-Authored-By: Claude --- README.md | 1 + docs/audit-logs.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index b0b8ba8a..b38cccb3 100644 --- a/README.md +++ b/README.md @@ -970,6 +970,7 @@ _Libraries for file manipulation._ - File Type Detection - [mimetypes](https://docs.python.org/3/library/mimetypes.html) - (Python standard library) Map filenames to MIME types. - [python-magic](https://github.com/ahupp/python-magic) - A Python interface to the libmagic file type identification library. + - [magika](https://github.com/google/magika) - Detects file content types with a deep-learning model. **Media** diff --git a/docs/audit-logs.md b/docs/audit-logs.md index 5aad5c2f..14c6713e 100644 --- a/docs/audit-logs.md +++ b/docs/audit-logs.md @@ -40,6 +40,7 @@ Entries admitted as challengers without adoption-trajectory evidence, by maintai - seleniumbase -- admitted 2026-08-16 (PR #3284) as a Browser Automation challenger. It wraps selenium, the successor trajectory in the use case belongs to playwright, and its distinct value is its stealth/UC mode. Admitted because that stealth value counts toward Browser Automation. - semantica -- kept 2026-10-01 in the AI and Agents audit as a Data Layer challenger at 16,582 downloads/month on ClickPy, with no adoption-trajectory evidence found. Kept by maintainer decision. - hyperopt -- admitted 2026-10-16 as a Hyperparameter Optimization challenger at 1,793,872 downloads/month on ClickPy. Its 0.3.0 release came after a 4.5-year gap and it has no adoption-trajectory evidence. Admitted by maintainer decision. +- magika -- admitted 2026-10-16 as a File Type Detection challenger at 16,388,380 downloads/month on ClickPy. markitdown requires it, so most of that count is transitive, and no adoption-trajectory evidence was found. Admitted by maintainer decision. ### Cap Exceptions From 7de9a00a67e0f353f12ecbfd9def9464a5a25db9 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:26:44 +0800 Subject: [PATCH 27/31] feat: add cloudpickle to Serialization > Object Pickling Pickling arbitrary Python objects is a different job from data formats, so Serialization splits into Data Formats and Object Pickling. Co-Authored-By: Claude --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b38cccb3..3d43a265 100644 --- a/README.md +++ b/README.md @@ -504,10 +504,13 @@ _Libraries and software for indexing and performing search queries on data._ _Libraries for serializing complex data types._ -- [msgpack](https://github.com/msgpack/msgpack-python) - MessagePack serializer implementation for Python. -- [orjson](https://github.com/ijl/orjson) - Fast, correct JSON library. -- [marshmallow](https://github.com/marshmallow-code/marshmallow) - A lightweight library for converting complex objects to and from simple Python datatypes. -- [msgspec](https://github.com/msgspec/msgspec) - A fast serialization and validation library with built-in support for JSON, MessagePack, YAML, and TOML. +- Data Formats + - [msgpack](https://github.com/msgpack/msgpack-python) - MessagePack serializer implementation for Python. + - [orjson](https://github.com/ijl/orjson) - Fast, correct JSON library. + - [marshmallow](https://github.com/marshmallow-code/marshmallow) - A lightweight library for converting complex objects to and from simple Python datatypes. + - [msgspec](https://github.com/msgspec/msgspec) - A fast serialization and validation library with built-in support for JSON, MessagePack, YAML, and TOML. +- Object Pickling + - [cloudpickle](https://github.com/cloudpipe/cloudpickle) - Extends pickle to functions, lambdas, and interactively defined classes, for shipping code to remote workers. **Data & Science** From cf2667a14558f5a159f706154d5f36af4b3ca692 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:26:49 +0800 Subject: [PATCH 28/31] feat: add dill to Serialization > Object Pickling Co-Authored-By: Claude --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3d43a265..2cd7fa64 100644 --- a/README.md +++ b/README.md @@ -511,6 +511,7 @@ _Libraries for serializing complex data types._ - [msgspec](https://github.com/msgspec/msgspec) - A fast serialization and validation library with built-in support for JSON, MessagePack, YAML, and TOML. - Object Pickling - [cloudpickle](https://github.com/cloudpipe/cloudpickle) - Extends pickle to functions, lambdas, and interactively defined classes, for shipping code to remote workers. + - [dill](https://github.com/uqfoundation/dill) - Extends pickle to serialize almost any Python object, including closures and whole interpreter sessions. **Data & Science** From 3322bb3ce75e5788cc08242ecae54f9e5d1ef7dc Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:26:54 +0800 Subject: [PATCH 29/31] feat: add betterleaks to Supply Chain Security > Secret Scanning Leaked secrets are a supply chain risk that dependency audits don't cover, so Supply Chain Security splits into Dependency Audits and Secret Scanning. Co-Authored-By: Claude --- README.md | 9 ++++++--- website/data/pypi_name_overrides.json | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2cd7fa64..ee4bd8ff 100644 --- a/README.md +++ b/README.md @@ -1163,10 +1163,13 @@ _Frameworks and tools for penetration testing._ ### Supply Chain Security -_Tools for auditing dependencies against known vulnerabilities._ +_Tools for auditing dependencies against known vulnerabilities and scanning for leaked secrets._ -- [pip-audit](https://github.com/pypa/pip-audit) - Audits Python environments and dependency trees for known vulnerabilities, using the Python Packaging Advisory Database or OSV. -- [uv-audit](https://github.com/astral-sh/uv) - (part of uv) uv's [dependency vulnerability scanning](https://docs.astral.sh/uv/reference/cli/#uv-audit) backed by OSV. +- Dependency Audits + - [pip-audit](https://github.com/pypa/pip-audit) - Audits Python environments and dependency trees for known vulnerabilities, using the Python Packaging Advisory Database or OSV. + - [uv-audit](https://github.com/astral-sh/uv) - (part of uv) uv's [dependency vulnerability scanning](https://docs.astral.sh/uv/reference/cli/#uv-audit) backed by OSV. +- Secret Scanning + - [betterleaks](https://github.com/betterleaks/betterleaks) - Finds leaked secrets in git history, directories, and files, from the original author of gitleaks. ### Web Security diff --git a/website/data/pypi_name_overrides.json b/website/data/pypi_name_overrides.json index 184197e7..0ee6dfa6 100644 --- a/website/data/pypi_name_overrides.json +++ b/website/data/pypi_name_overrides.json @@ -1,6 +1,7 @@ { "autobahn-python": { "package": "autobahn", "reason": null }, "azure-sdk-for-python": { "package": null, "reason": "monorepo umbrella; ships as many azure-* packages, no single package represents it", "badge": "Multiple on PyPI" }, + "betterleaks": { "package": null, "reason": "not published on PyPI" }, "cloud-init": { "package": null, "reason": "installed via distro images, not pip" }, "concurrent-futures": { "package": null, "reason": "stdlib module" }, "conda": { "package": null, "reason": "installed via Miniforge or Anaconda installers; PyPI conda is a stale 2017 upload" }, From e2ead5fc84b9e3e506fe804fc55e816c03443813 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:35:09 +0800 Subject: [PATCH 30/31] style: capitalize Python in entry descriptions Co-Authored-By: Claude --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ee4bd8ff..e2ae0b7a 100644 --- a/README.md +++ b/README.md @@ -557,7 +557,7 @@ _Libraries for visualizing data. Also see [awesome-javascript](https://github.co - [bokeh](https://github.com/bokeh/bokeh) - Interactive Web Plotting for Python. - Specialized - [graphviz](https://github.com/xflr6/graphviz) - Simple Python interface for creating and rendering Graphviz graphs. - - [cartopy](https://github.com/SciTools/cartopy) - A cartographic python library with matplotlib support. + - [cartopy](https://github.com/SciTools/cartopy) - A cartographic Python library with matplotlib support. - [graphify](https://github.com/Graphify-Labs/graphify) - Turn any folder of code, SQL schemas, docs, papers, images, or videos into a queryable knowledge graph. - Dashboards and Apps - [streamlit](https://github.com/streamlit/streamlit) - A framework which lets you build dashboards, generate reports, or create chat apps in minutes. @@ -657,7 +657,7 @@ _Tools of static analysis, linters and code quality checkers. Also see [awesome- - [awesome-flake8-extensions](https://github.com/DmytroLitvinov/awesome-flake8-extensions) - [bandit](https://github.com/PyCQA/bandit) - A tool designed to find common security issues in Python code. - Refactoring - - [rope](https://github.com/python-rope/rope) - Rope is a python refactoring library. + - [rope](https://github.com/python-rope/rope) - Rope is a Python refactoring library. - [ast-grep-cli](https://github.com/ast-grep/ast-grep) - A CLI tool for structural code search, linting, and rewriting based on syntax trees. - Type Checkers - [awesome-python-typing](https://github.com/typeddjango/awesome-python-typing) - [mypy](https://github.com/python/mypy) - A static type checker for Python. @@ -885,7 +885,7 @@ _Libraries for working with graphical user interface applications._ - [PyQt6](https://www.riverbankcomputing.com/static/Docs/PyQt6/) - Python bindings for the [Qt](https://www.qt.io/) cross-platform application and UI framework. - Tkinter - [tkinter](https://docs.python.org/3/library/tkinter.html) - (Python standard library) The standard Python interface to the Tcl/Tk GUI toolkit. - - [customtkinter](https://github.com/tomschimansky/customtkinter) - A modern and customizable python UI-library based on Tkinter. + - [customtkinter](https://github.com/tomschimansky/customtkinter) - A modern and customizable Python UI-library based on Tkinter. - Web-based - [pywebview](https://github.com/r0x0r/pywebview) - A lightweight cross-platform native wrapper around a webview component. - [nicegui](https://github.com/zauberzeug/nicegui) - An easy-to-use, Python-based UI framework, which shows up in your web browser. @@ -969,7 +969,7 @@ _Libraries for file manipulation._ - Paths and File Watching - [pathlib](https://docs.python.org/3/library/pathlib.html) - (Python standard library) A cross-platform, object-oriented path library. - - [watchfiles](https://github.com/samuelcolvin/watchfiles) - Simple, modern and fast file watching and code reload in python. + - [watchfiles](https://github.com/samuelcolvin/watchfiles) - Simple, modern and fast file watching and code reload in Python. - [watchdog](https://github.com/gorakhargosh/watchdog) - API and shell utilities to monitor file system events. - File Type Detection - [mimetypes](https://docs.python.org/3/library/mimetypes.html) - (Python standard library) Map filenames to MIME types. @@ -1128,7 +1128,7 @@ _Libraries to create packaged executables for release distribution._ - [pex](https://github.com/pex-tool/pex) - A tool for building self-contained Python executable environments (PEP 441 zipapps). - [cx-Freeze](https://github.com/marcelotduarte/cx_Freeze) - Converts Python scripts into standalone executables and installers for Windows, macOS, and Linux. - Obfuscation - - [pyarmor](https://github.com/dashingsoft/pyarmor) - A tool used to obfuscate python scripts, bind obfuscated scripts to fixed machine or expire obfuscated scripts. + - [pyarmor](https://github.com/dashingsoft/pyarmor) - A tool used to obfuscate Python scripts, bind obfuscated scripts to fixed machine or expire obfuscated scripts. ### Configuration Files From 9516fb7af559a7b02bdf3057a81b44202c591f31 Mon Sep 17 00:00:00 2001 From: Vinta Chen Date: Fri, 16 Oct 2026 17:42:06 +0800 Subject: [PATCH 31/31] fix: keep stars listed through a binding out of later scans The scanner recognizes a star only when README links that exact repo, so a starred engine listed through its Python binding (llama.cpp as llama-cpp-python) came back as a new candidate every scan. The Record step now writes a ledger row for such stars. Also drops the last 'drop' verdict wording from preview-verdicts. Co-Authored-By: Claude --- .claude/skills/preview-verdicts/SKILL.md | 2 +- .claude/skills/scan-github-stars/SKILL.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.claude/skills/preview-verdicts/SKILL.md b/.claude/skills/preview-verdicts/SKILL.md index ee8dd716..ce363d06 100644 --- a/.claude/skills/preview-verdicts/SKILL.md +++ b/.claude/skills/preview-verdicts/SKILL.md @@ -18,7 +18,7 @@ Maintainer review happens through an interactive HTML page: one row per entry wi - Proposed new entry: `add` or `reject` (not added, logged under "Rejected Additions"). - Structure question: `restructure` (take the change the reason or group note describes), `park` (no record, so it resurfaces), or `reject` (logged under "Rejected Additions"); seed it `restructure` or `park`. - Show a replacement as two rows: the old entry `remove`, the new entry `add`. - - `reason` is plain language the maintainer reads cold — no invented shorthand. When fresh evidence contradicts the seeded verdict (a big download count on a drop, a dead repo on a keep), say so in that row's reason instead of silently changing the seed. + - `reason` is plain language the maintainer reads cold — no invented shorthand. When fresh evidence contradicts the seeded verdict (a big download count on a remove or reject, a dead repo on a keep), say so in that row's reason instead of silently changing the seed. 2. Copy `template.html` (sibling of this file) and replace the placeholders: `__TITLE__` (page title), `__SUB__` (sub-header: scope, seed provenance, fetch date, and the standing instruction to flip/comment then Copy feedback), `__KEY__` (localStorage key), `__DATA__` (the array). `__KEY__` must be unique per review — slug plus date, e.g. `awesome-python-science-2026-09-01` — because saved state under a reused key bleeds a previous review's flips into rows with the same section and entry name. 3. Write the page to `local/awesome-python--preview.html` in the repo root (git-ignored; create the directory if needed), `open` it, and tell the maintainer the path and the return path: flip or comment rows (they highlight yellow), press **Copy feedback**, paste the JSON into the chat. Done when the page is open and the return path is stated. diff --git a/.claude/skills/scan-github-stars/SKILL.md b/.claude/skills/scan-github-stars/SKILL.md index 5ef612c3..3b019986 100644 --- a/.claude/skills/scan-github-stars/SKILL.md +++ b/.claude/skills/scan-github-stars/SKILL.md @@ -29,7 +29,7 @@ Run `preview-verdicts` over all groups: survivors as `add` or `reject` rows, dis ## 5. Record -- **Added**: follow `audit-the-list` step 5 for the README change, one commit per entry. +- **Added**: follow `audit-the-list` step 5 for the README change, one commit per entry. When the entry links a different repo than the star (a Python binding or client of a starred engine), also append a ledger row `already listed as ()` for the star, since the script only recognizes a star whose own repo is linked. - **Rejected**: a candidate that reached review and was not added gets one line under "Rejected Additions": `- owner/repo -- yyyy-mm-dd, /month (): .`, replacing its earlier line. - **Parked**: a row the maintainer parks gets no record, so it resurfaces next run.
EntrySourceDownloads/moMy verdictMy reasonYoursYour reason (optional)
${name}${source || ""}${dl} ${mine.toUpperCase()} ${reason} - ${mine === "add" - ? `` - : ``} - + ${CHOICES[mine].map(v => ``).join("")}