Skip to content

Releases: FlorianBruniaux/starmapper

v0.6.9 — MCP expanded to 15 tools

Choose a tag to compare

@FlorianBruniaux FlorianBruniaux released this 18 Jun 19:13

MCP server: 10 tools → 15

Five new tools covering the features added in 0.6.7/0.6.8 that had no MCP surface yet.

New tools

get_contributors — top 50 contributors of a repo with commit count. Pass with_locations: true to enrich each contributor with their geocoded location from StarMapper data.

get_followers — top 100 followers of any GitHub user, sorted by their own follower count. Includes company and location per follower.

get_country_stats — full country and city breakdown for a repo already indexed on StarMapper. Returns all countries and top 30 cities.

get_global_country_stats — cross-repo developer distribution by country from the country_stats_mv materialized view. Total stargazer count in the header.

get_dependencies — a repo's own dependency graph via the GitHub SBOM API: package name, ecosystem, version. Returns a clean message (not an error) when the dependency graph is disabled on the repo.

Under the hood

  • 4 new API routes: /api/mcp/contributors/[owner]/[repo] (supports ?withLocations=1), /api/mcp/followers/[login], /api/mcp/country-stats, /api/mcp/dependencies/[owner]/[repo]
  • fetchRepoDependencies() added to src/lib/github.ts: SBOM endpoint, purl parsing, dedup by ecosystem+name, root SPDX package filtered
  • validateLogin() added to src/lib/api-validation.ts
  • 44 new tests (1050 total, all passing)
  • starmapper-mcp bumped to 0.2.0

Full changelog

https://starmapper.bruniaux.com/changelog

v0.6.4

Choose a tag to compare

@FlorianBruniaux FlorianBruniaux released this 10 Jun 16:11

Repos table

The /repos community maps table gains a filter bar and a dependents column. The filter bar provides language chip toggles (computed from the top 8 languages by count), a "Has dependents" chip, and a "Has score" chip; chips are combinable and a count badge shows the filtered result set size. A "Deps" column (hidden below lg breakpoint) links to the dependents page for repos with data and is sortable alongside the existing stars, mapped %, countries, score, and last-scan columns. The underlying GET /api/repos response now includes dependentsCount: number | null via a LEFT JOIN on dependents_cache filtered to non-expired rows.

Dependents table

Each row in /[owner]/[repo]/dependents gains a flag icon (red on hover) that opens a pre-filled GitHub issue for reporting an incorrect dependent. The issue template includes the library name, the reported dependent, its ecosystem, its package name, and a link to ecosyste.ms for reference.

Landing page

The "Dependents Explorer" and "MCP Server" cards in the "More to Explore" section were converted from wide two-column cards to standard single-column grid cards, matching the layout of the other four cards in the section.

Bug Fixes

  • scripts/db/db-sync-from-neon.sh: follower_cache and dependents_cache were missing from the default TABLES list. Running pnpm db:sync:from-neon would silently skip both tables. Both are now included with correct column lists and ON CONFLICT upsert clauses.

v0.6.2 — SEO and Progressive Web App

Choose a tag to compare

@FlorianBruniaux FlorianBruniaux released this 09 Jun 07:13

SEO and Progressive Web App

StarMapper now ships full Open Graph metadata, a PWA web manifest, and JSON-LD structured data sitewide. Every page generates a dynamic og:image at /api/og via @vercel/og. The root opengraph-image.tsx handles all pages that don't define their own image, while the repo map page already had its own OG image since 0.5.x. A manifest.ts registers the app name, icons, and theme colors for "Add to Home Screen" on mobile. Structured data (JSON-LD WebSite + SoftwareApplication schemas) is injected in the root layout.

New files

  • src/app/manifest.ts
  • src/app/opengraph-image.tsx
  • src/app/sitemap.ts
  • src/app/robots.ts
  • src/app/icon.svg

v0.6.1 — Followers Map: user switcher

Choose a tag to compare

@FlorianBruniaux FlorianBruniaux released this 09 Jun 07:12

Followers Map: User Switcher

On the /[owner]/followers page, users can now navigate to any other GitHub user's followers map without leaving the page. A compact @login / trigger in the header opens a command-palette modal that queries the GitHub Search API with a 200 ms debounce, showing up to 8 user results with avatars. Keyboard navigation (↑↓ Enter Escape) and the / global shortcut are supported.

New files

  • src/components/followers-user-switcher.tsx: trigger button + modal component
  • src/app/api/users/autocomplete/route.ts: GET /api/users/autocomplete?q= proxies GitHub search/users, returns { login, name, avatarUrl }[], 60 s CDN cache

v0.6.0 — starmapper-mcp: Claude Code / MCP integration

Choose a tag to compare

@FlorianBruniaux FlorianBruniaux released this 09 Jun 07:12

Claude Code / MCP Integration

starmapper-mcp is a standalone npm package that wraps StarMapper's API as an MCP (Model Context Protocol) server. Claude Code users can query any indexed repo's audience data from the terminal, trigger re-indexation, and get audience breakdowns directly in their AI conversations.

{ "mcpServers": { "starmapper": { "command": "npx", "args": ["starmapper-mcp"] } } }

Nine tools

  • get_repo_stats: total stars, geocoded count, top countries, top cities, organic score summary
  • get_organic_score: signal breakdown with weights, active signals, reasons, and 85.7% corpus accuracy label
  • get_velocity: per-country star velocity (last 30 days vs prior 60-day window) with rising / new / stable / declining labels
  • get_influential_stargazers: stargazers above a follower threshold (default 500, max 1,000,000), sorted by influence, capped at 50 results
  • index_repo: drives the full chunk loop from the MCP client, geocodes all stargazers, and saves the result to StarMapper's shared cache
  • health_check: pings the StarMapper API and returns status and latency
  • get_cache_status: returns cache metadata for a repo (scanned date, mapped count, total) without transferring the full stargazer blob
  • get_trending: returns the current trending repos from StarMapper's trending feed
  • list_repos: lists all repos indexed on StarMapper, ordered by last scan date

New API routes

  • GET /api/mcp/organic-score/[owner]/[repo]: full organic score signal breakdown. Recomputes signals live. Public. Cache-Control: public, s-maxage=300, stale-while-revalidate=600.
  • GET /api/mcp/influential/[owner]/[repo]?minFollowers=N: influential stargazers above a follower threshold (0 to 1,000,000, default 500). Public, no auth gate. Hard-capped at 50 results.

Set STARMAPPER_BASE_URL to point at a self-hosted instance.

v0.5.9 — Followers Map

Choose a tag to compare

@FlorianBruniaux FlorianBruniaux released this 09 Jun 07:04

Followers Map

A GitHub user's followers can now be mapped, exactly like a repo's stargazers. Every developer profile on StarMapper gains a /[owner]/followers page: an interactive map with GeoJSON clustering, a side panel listing followers sorted by influence (follower count), fly-to on click, and virtual scroll for large lists.

  • /[owner]/followers page: full-screen map + FollowersPanel side panel with virtual scroll, fly-to on marker click, and a summary badge (mapped / total).
  • Profile page entry points: the followers count badge on /profile/[login] is now a link to the followers map. A "Map followers" action button appears in the profile actions row.
  • Announcement banner + More to Explore: the site-wide banner promotes the followers map feature; the "More to Explore" section on the landing page includes a followers map card.
  • /api/followers-chunk: new POST endpoint. Fetches 100 followers per call via GitHub GraphQL, geocodes locations through the standard 3-tier cascade (Jawg, Geoapify, Nominatim), applies the 30-day stale cache strategy, and returns FollowerPoint[] + unmapped[]. Distributed rate limiting via Upstash (30 req/min per IP, 300 req/h per PAT).
  • useFollowersScanController: client-side hook that drives the /api/followers-chunk loop sequentially, accumulates points progressively, and surfaces quota remaining.

Ops scripts

  • scripts/ops/index-followers.ts: single-user followers geocache warm-up.
  • scripts/ops/batch-index-followers.ts: batch geocache warm-up for all users in DB with ≥N followers (default 100). Calls fetchFollowersPage + geocodeBatch directly, no HTTP server required. Multi-token rotation.
  • scripts/ops/index-repo.ts: drives the /api/chunk loop for any repo to pre-warm its geocache.

Bug Fixes

  • Followers page sticky header: fixed map overlap caused by non-sticky header on the followers page.
  • Touch targets on FollowersPanel: replaced arbitrary Tailwind values with standard spacing classes for 44px minimum touch targets.

v0.5.8 — WCAG AA accessibility pass and SEO metadata

Choose a tag to compare

@FlorianBruniaux FlorianBruniaux released this 09 Jun 07:04

Accessibility

  • WCAG AA pass, 9 violations fixed. Six text inputs (explore city search, login/name search, profile repo search, [owner] repo search and min-stars filter, map top-panel username input) were missing accessible names and now carry explicit aria-label attributes. The min-stars <label> is now programmatically linked via htmlFor/id. The StarNudge popup (role: dialog) gains keyboard dismissal via Escape. The unmapped-stargazers bottom drawer gains role="region", aria-label, and Escape-to-close.
  • Dark-mode contrast raised to WCAG AA. text-muted-subtle token in dark mode bumped from #848d97 (4.2:1 ratio) to #8b929a (~4.55:1). Affects secondary labels, breadcrumb separators, and stat hints across all pages.

SEO

  • Metadata added to two high-traffic unindexed routes. /trending now has a dedicated layout.tsx with title, description, OG, Twitter card, and canonical. /[owner] (user scan page) has generateMetadata producing a dynamic title {owner}'s repos | StarMapper and a canonical URL.
  • OG / Twitter / canonical added to 6 secondary pages. /privacy, /terms, /legal, /changelog, /sponsor, and /organic-score/calibration now carry full social metadata.
  • JSON-LD root sanitization aligned. Root layout.tsx now applies .replace(/</g, "\\u003c") on the JSON-LD payload, consistent with the per-repo and profile layouts.

Performance

  • Three raw <img> tags in /explore replaced with <Image>. Avatar thumbnails in the Top Contributors, Power Users, and Nearby Developers panels now use Next.js <Image> with loading="lazy", enabling automatic AVIF/WebP delivery.

v0.5.7 — App Router SC/CC split on 3 pages

Choose a tag to compare

@FlorianBruniaux FlorianBruniaux released this 09 Jun 07:04

Performance

  • App Router SC/CC split on 3 major pages. [owner]/[repo], /explore, and /profile/[login] were monolithic "use client" pages with no server-side rendering. Each now has a Server Component wrapper that pre-fetches the critical-path data (repo info, explore summary, profile) and passes it as initialData to the client component. The client-side fetch becomes a fallback (private repo, 404, network error) instead of the default path. LCP improves for all three routes; crawlers and social preview bots see real HTML content on first byte.
  • map-style-urls.ts extracted from theme.ts. MAP_STYLE_DARK, MAP_STYLE_LIGHT, Theme, and MapProjection moved to a server-safe module with no "use client" marker. theme.ts re-exports them for backward compatibility. Prevents accidental bundle pollution if a server component ever imports map URL builders.

Bug Fixes

  • sanitizeError missing from refresh-grid-mv test mock. The route imported sanitizeError from @/lib/api-helpers but the Vitest mock factory did not expose it. The function was added to the mock; the 1 failing test now passes (895/895).

Internal

  • JawgBadge component made server-safe. "use client" removed from src/components/map/jawg-badge.tsx. The component is a static <a> tag with no hooks or browser APIs.

v0.5.6 — DB query optimization and GDPR atomicity

Choose a tag to compare

@FlorianBruniaux FlorianBruniaux released this 09 Jun 07:04

Performance

  • Prisma query payload reduction. Five findUnique calls without select now fetch only the columns actually consumed: badge-update fetches totalCount only (was all 15+ columns), map-image fetches 4 badge columns, stargazer-cache GET fetches updatedAt for the fallback path and explicit 5-column select for the full row. Reduces data transferred from Neon on every scan completion and every map image generation.
  • organic-score-stats SQL aggregate. The admin stats endpoint was loading all badge_cache rows into Node.js memory for in-memory aggregation. Replaced with two parallel $queryRaw GROUP BY queries (per-tier counts + per-bucket distribution via width_bucket). Memory footprint is now O(1) regardless of table size.

Internal

  • import-geocache bulk upsert. N+1 pattern replaced with a single $queryRaw UNNEST INSERT ... ON CONFLICT DO UPDATE per batch of 500. Same pattern as bulkUpsertUsers in user-cache.ts. Admin dev-only route, blocked in production.
  • GDPR deletion atomicity. delete-user route wraps starEvent.deleteMany + gitHubUser.delete in prisma.$transaction([...]). Prevents partial deletion if the process crashes between the two operations.

v0.5.5 — Token modal UX and freshness communication

Choose a tag to compare

@FlorianBruniaux FlorianBruniaux released this 09 Jun 07:03

UX

  • Token modal clarity. Reframed "GitHub Access Token" as "Speed Boost: GitHub Token" to remove the auth/login connotation. Added a trust banner ("No account, no login, no signup. A GitHub token is just a speed pass for the API") with a Shield icon. Copy simplified: 60 vs 5,000 req/hr now explicit, link reads "Create a free token (zero permissions)". Modal widened to max-w-lg. Browser-native password reveal/autofill icons suppressed via CSS.
  • Data freshness communication. A "Data updates when someone refreshes, not in real time." line now appears under the cache status row. Lock icon tooltips on Refresh and Full rescan buttons explain "Add a free GitHub token for faster scanning. No login needed."
  • Community cache model explained. Pre-scan overlay rewritten: "Results are shared with everyone. When you scan, all future visitors see your results instantly." The 50k+ token warning now says "free token / zero permissions / no login, no signup."
  • FAQ additions. Two new entries: "Do I need to create an account?" and "Is the data real-time?" Fixed a factual error: token storage was documented as localStorage but the implementation uses sessionStorage with a 30-minute TTL.
  • Watch Mode wording. Tour step and dock button title replace "real time" with "polls GitHub every 60 seconds" for accuracy.
  • Landing one-liner. A three-step summary added below the community count: "1. Paste a repo · 2. We scan GitHub · 3. Everyone sees the map".
  • Header / floating nav. Token button label changed from "Add token" to "Faster scans" when no token is set.
  • Privacy page. sessionStorage token storage and 30-minute TTL documented.