Skip to content

Repository files navigation

Starboard

Data Enrichment

A self-hosted admin console for your GitHub starred repositories — auto-enriched by LLM and published to GitHub Pages.

What it does

  • Fetches all starred repos via the GitHub API
  • Enriches each repo with GitHub REST metadata plus an LLM-generated category, summary, and watch note using GitHub Models (free tier)
  • Smart re-enrichment — skips LLM work whose source metadata hasn't changed and skips REST metadata refreshes when the repo has not moved since the last successful extended fetch
  • Privacy-filtered publishing — keeps the canonical local dataset in data/stars.json and publishes only public repos to the static site
  • Daily public history snapshots — records data/history.json for analytics and publishes the public copy alongside the site
  • Topic discovery engine — generates data/discoveries.json from GitHub topic search plus curated synonym groups, and publishes a public-only site/public/data/discoveries.json
  • Publishes an admin console dashboard to GitHub Pages, refreshed daily via GitHub Actions

Dashboard

A dense dashboard with sidebar navigation and workspace tools:

  • Sidebar: All / Watch / Discover / Cleanup / Not Enriched + dynamic LLM category counts
  • Workspace strip: visible-repo stats, topic cloud, and export actions
  • Table: multi-column sorting for repository, category, stars, and activity
  • Filters: category, language, status, stars range, and topics
  • Search: full-text across name, summary, description
  • Row detail modal: repository metadata, LLM fields, and Phase 1 extended GitHub data
  • Compare: select 2–4 repos for side-by-side comparison with aggregate metrics
  • Analytics: timeline, category and language breakdowns, portfolio health, and trending panels over public daily history snapshots

Status chips:

  • Watch — active, non-archived repos with recent pushes
  • Stale — enriched repos with no recent activity
  • Cleanup — archived or long-inactive repos
  • Pending — not yet enriched

Setup

1. Fork this repository

2. Create two Personal Access Tokens

GH_STARS_PAT — fetches your starred repos:

  • Classic PAT → scopes: read:user, public_repo
  • Add repo scope if you want private starred repos included (see Privacy)
  • Create at: Settings → Developer settings → Personal access tokens → Tokens (classic)

GH_MODELS_PAT — calls the LLM enrichment API:

  • Fine-grained PAT → permission: Models → Read
  • Create at: Settings → Developer settings → Personal access tokens → Fine-grained tokens

3. Add secrets to the repository

Settings → Secrets and variables → Actions → New repository secret:

Name Value
GH_STARS_PAT your classic PAT
GH_MODELS_PAT your fine-grained PAT

4. Enable GitHub Pages

Settings → Pages → Source: GitHub Actions

5. Trigger the first run

Actions → Refresh Starboard → Run workflow


Local usage

# Install dependencies
pip install -r requirements.txt

# Configure tokens
cp .env.example .env
# edit .env — set GH_STARS_PAT and GH_MODELS_PAT

# Run the pipeline
python scripts/fetch_stars.py       # fetch stars + compute heuristics
python scripts/enrich_stars.py      # LLM enrichment (requires GH_MODELS_PAT)
python scripts/build_site.py        # write privacy-filtered data to site/

# View the dashboard
cd site
npm install
npm run dev
# → open http://localhost:5173/

Configuration

Edit config.json.

Heuristics

"heuristics": {
  "recent_star_days": 30,
  "recent_activity_days": 90,
  "stale_days": 365
}
  • watch_candidate = not archived AND pushed within recent_activity_days
  • cleanup_candidate = archived OR not pushed for stale_days

Model chain

Models are tried in order; on rate limit or error the next one is used:

"models": {
  "chain": [
    {"id": "openai/gpt-4o",        "family": "openai"},
    {"id": "openai/gpt-4.1-mini",  "family": "openai"},
    ...
  ]
}

All models are available on the GitHub Models free tier.

Discovery

Controls how many source repositories are processed per run:

"discovery": {
  "source_repo_limit": 30
}

Set lower during development to reduce API calls. Invalid or missing values fall back to 30.

Topic synonyms

Discovery uses a curated map of topic groups to expand topic-based search coverage without an LLM:

"topic_synonyms": {
  "claude-code": ["gemini-cli", "copilot-cli", "codex-cli", "..."],
  "mcp": ["mcp-server", "mcp-tools", "..."]
}

Keep the list small, explicit and function-oriented so the suggestions stay useful. Topic co-occurrence is also computed automatically from the user's own starred repos and merged with this map at runtime.

LLM prompt

Edit prompts/enrich.txt — it is versioned and applied at enrichment time.


Smart re-enrichment

fetch_stars.py hashes each repo's relevant metadata (description, topics, language, archived). On subsequent runs, existing LLM data is preserved when:

  1. The content hash matches (no relevant metadata changed), and
  2. The enrichment is less than 30 days old

Repos that fail either condition are queued for re-enrichment. The run prints a summary:

Re-enrichment queued: 3 repos (1 content_changed, 2 aged_31d)

fetch_stars.py also caches extended GitHub REST metadata separately from the LLM fields. License, latest release, README excerpt, contributor count, 52-week commit activity and community health data are reused while cached_pushed_at matches the repo's current pushed_at/updated_at. Transient endpoint failures and README decode errors do not advance cached_pushed_at, so a later run can retry instead of freezing incomplete metadata.

build_history.py turns the public subset of data/stars.json into a daily snapshot file keyed by UTC date. The canonical data/history.json and the public site/public/data/history.json are both updated in place, so reruns on the same day stay idempotent instead of duplicating snapshots.

discover_similar.py builds discovery suggestions from the canonical stars dataset using three complementary signals: topic search expanded through curated config.json synonyms plus auto-computed topic co-occurrence from the user's own starred repos; in:description keyword queries derived from existing llm_summary fields (no new model calls); and a fallback path for repos with no GitHub topics that uses keyword queries as primary signal. Each discovery entry records seed_keywords alongside seed_topics for transparency. Writes data/discoveries.json and the public site/public/data/discoveries.json, keeping only public sources and suggestions in the published copy.


Privacy

If your GH_STARS_PAT has repo scope, private or internal repositories you have starred can be included in the canonical data/stars.json.

scripts/build_site.py refuses to publish entries without visibility metadata and writes only repositories with visibility == "public" to site/public/data/stars.json. Still review data/stars.json before committing or sharing it, or restrict the token to public_repo only.


Structure

config.json                   heuristics + model chain
prompts/enrich.txt            LLM prompt template
scripts/
  fetch_stars.py              fetch stars, REST metadata, heuristics + content hash
  enrich_stars.py             LLM enrichment via GitHub Models
  build_history.py            daily public history snapshots for analytics
  discover_similar.py         topic + keyword discovery with co-occurrence and fallback
  build_site.py               write privacy-filtered data to site/public/data/
  validate_models.py          smoke-test model chain availability
data/
  stars.json                  canonical source of truth, may include non-public repos
  history.json                daily public history snapshots for analytics
  discoveries.json            topic-based discovery suggestions
site/
  src/                        React + TypeScript dashboard source
  public/data/stars.json      privacy-filtered runtime data for the SPA
  public/data/history.json     public daily history snapshots for analytics
  public/data/discoveries.json public discovery suggestions
  dist/                       production build output
tests/
  test_fetch_stars.py         unit tests — content hash + re-enrichment logic
  test_enrich_stars.py        unit tests — LLM payload + retry classification
  test_phase1_enrichment.py   unit tests — Phase 1 REST metadata + privacy filter
  test_build_history.py       unit tests — public history snapshot writer
  test_discover_similar.py    unit tests — topic discovery pipeline + public filtering
.github/workflows/refresh.yml daily refresh + Pages deploy

About

Static dashboard for GitHub starred repositories — enriched with LLM summaries via GitHub Models

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages