Classification tool and brew data made for CaskHub — a GUI macOS application for Homebrew Casks.
categories.json— canonical mapping from cask token → category, plus the category list itself. CaskHub fetches the latest copy from GitHub Releases and ships a bundled fallback.added_dates.json— cask token → date it entered homebrew-cask, mined from the tap's git history byscripts/mine_added_dates.pyat release time (not committed; regenerated per release). Powers CaskHub's Recently Added 30/60/90-day windows.scripts/— Python pipeline that classifies new casks, prunes deprecated/removed ones, and writescategories.json.docs/CLASSIFICATION_GUIDE.md— category definitions and boundary rules. Source of truth for both the LLM system prompt and human reviewers.docs/ICON_EXTRACTION.md— how app icons are extracted from cask artifacts and published to theiconsbranch.data/— historical artifacts (homepage scrape cache, audit reports, manual correction history). Regenerated by the pipeline; not authoritative.
A daily GitHub Actions cron (.github/workflows/classify-new-casks.yml):
- Fetches
formulae.brew.sh/api/cask.json. - Computes the diff against
categories.json—new_tokens,removed_tokens,deprecated_tokens. - Scrapes homepages for new tokens only (delta cache).
- Classifies each new token with an LLM (provider-agnostic; default Claude Haiku 4.5).
- Prunes removed/deprecated tokens.
- Opens a single rolling PR with the diff + classification report.
On merge, release.yml cuts a caskflow-vYYYY.MM.DD tag with categories.json and a freshly mined added_dates.json attached as release assets.
A second daily cron (.github/workflows/extract-icons.yml) extracts original app icons from cask artifacts — downloaded, expanded without executing anything, and rendered to 256×256 PNGs. Icons live on the orphan icons branch (one PNG per cask token) and are served to CaskHub through jsDelivr's CDN:
https://cdn.jsdelivr.net/gh/alielsokary/CaskFlow@icons/<token>.png
It runs after the classification cron, so a new cask usually gets its category and its icon on the same day. Details and audit protocol: docs/ICON_EXTRACTION.md.
pip install -r requirements.txt
# Dry-run with the deterministic mock provider
LLM_PROVIDER=mock python scripts/classify_new_casks.py
# Real classification (requires API key)
LLM_PROVIDER=anthropic ANTHROPIC_API_KEY=sk-... python scripts/classify_new_casks.pySet LLM_PROVIDER to one of: anthropic (default), openai, groq, cloudflare, mock. Each implementation lives in scripts/llm_client.py. Switching providers is a single env-var change; the prompt and validation logic are shared.
categories.json is versioned. Schema changes require bumping the version field — CaskHub rejects mismatched-version payloads at runtime and falls back to its bundled copy.
MIT — see LICENSE.