Skip to content

feat(extension): add Chrome MV3 tombstone badge for GitHub repo pages#23

Merged
dotsystemsdevs merged 1 commit intodotsystemsdevs:mainfrom
mvanhorn:osc/14-chrome-extension-tombstone-badge
Apr 27, 2026
Merged

feat(extension): add Chrome MV3 tombstone badge for GitHub repo pages#23
dotsystemsdevs merged 1 commit intodotsystemsdevs:mainfrom
mvanhorn:osc/14-chrome-extension-tombstone-badge

Conversation

@mvanhorn
Copy link
Copy Markdown
Contributor

Summary

Closes #14. Adds a Manifest V3 Chrome extension under extension/ that injects a 🪦 "Declared Dead — View Certificate" badge near the repo title on any github.com/<owner>/<repo> page where commitmentissues.dev/api/repo reports deathIndex >= 6. Click takes the user to the certificate at commitmentissues.dev/?repo=<owner>/<repo>.

Why this matters

Issue #14 spelled out the UX: developers don't always remember to check commitmentissues.dev before they evaluate a dependency. A passive in-place badge surfaces the verdict at the moment they're already on the repo page, with zero friction to dig deeper if they care.

Changes

  • NEW extension/manifest.json — MV3, content-script-only. host_permissions is just https://commitmentissues.dev/* (no broad <all_urls>); matches: ["https://github.com/*"]. No background service worker per the issue's MVP scope.
  • NEW extension/content.js — single self-invoking module:
    • parseRepoFromPath peels owner/repo out of /owner/repo/.... It excludes GitHub's reserved top-level paths (orgs, settings, explore, topics, trending, events, sponsors, marketplace, pricing, etc.) and per-user reserved second segments (followers, following, projects, tabs) so org pages and profile sub-pages don't get a badge.
    • findRepoTitleAnchor tries three known-stable selectors (strong[itemprop="name"] a, h1 strong[itemprop="name"] a, h1 a[data-pjax="#repo-content-pjax-container"]) so we degrade gracefully if GitHub tweaks one.
    • fetchDeathIndex calls /api/repo?url=<gh url> with AbortSignal.timeout(4000) (with a polyfill fallback), then reads body.deathIndex. Anything non-numeric, non-200, or thrown -> silent skip.
    • tryInject removes any prior badge, short-circuits when lastInjectedFor === fullName, runs the fetch, and re-checks the URL after the await so we don't drop a stale badge if the user navigated mid-fetch.
    • observeNavigation listens for popstate + pjax:end + turbo:load + turbo:render and adds a MutationObserver on document.body that re-fires on href change. SPA navigation in either direction triggers a fresh tryInject.
  • NEW extension/icon.png — copy of src/app/icon.png per the issue's "reuse src/app/icon.png" note. Used as both the 32px and 128px icon in the manifest.
  • README.md — adds a "Browser extension" section with the 5-step load-unpacked instructions per the acceptance criteria.

Acceptance criteria

  • Badge appears on dead repos (deathIndex >= 6), not on active ones — both null/missing and < 6 paths exit silently before insertion.
  • No badge on non-repo GitHub pages — reserved top-level + second-segment lists are checked before any fetch.
  • No duplicate badge on SPA navigation — existing badge is removed at the start of each tryInject, and lastInjectedFor short-circuits identical re-renders.
  • API unavailable -> graceful silence — fetch is wrapped in a try/catch, non-200 returns null, timeout returns immediately.
  • Works in Chrome 114+ (MV3) — manifest_version: 3, AbortSignal.timeout (Chrome 103+).
  • Load-unpacked instructions in README updated.

Testing

  • python3 -c "import json; json.load(open('extension/manifest.json'))" — valid JSON.
  • node --check extension/content.js — clean.
  • Manual smoke test: loaded unpacked, visited a few known-dead and known-live repos to confirm the inject-once-and-link behavior. Org and profile pages remained un-badged. Forward/back navigation between repos correctly removed the old badge and (when applicable) inserted the new one.

This contribution was developed with AI assistance (Claude Code).

Closes dotsystemsdevs#14

Manifest V3 content script that injects a 🪦 "Declared Dead — View
Certificate" badge near the repo title on any github.com/<owner>/<repo>
page whose API entry has deathIndex >= 6. Click takes you to the
certificate at commitmentissues.dev/?repo=<owner>/<repo>.

Files:
- extension/manifest.json (MV3, host permission for commitmentissues.dev only)
- extension/content.js (parses repo from path, fetches /api/repo with
  AbortSignal.timeout(4000), inserts the badge once per repo, cleans up
  on SPA navigation via popstate + turbo:load + turbo:render + a
  href-watching MutationObserver)
- extension/icon.png (copy of src/app/icon.png as specified in dotsystemsdevs#14)

Acceptance criteria:
- Badge appears only on repo pages with deathIndex >= 6
- Reserved top-level paths (orgs, settings, explore, marketplace, etc.)
  and per-user subpaths (followers, following, projects, tabs) are
  excluded from the repo-detection
- No duplicate badge — lastInjectedFor short-circuits per fullName, plus
  a re-fetch is skipped when the location changes mid-await
- API unavailable / non-200 / timeout / fetch error -> silent skip
- README has load-unpacked instructions

Tested manually by loading the unpacked extension and visiting a few
known-dead and known-live repos to confirm the inject-once-and-link
behavior.
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 26, 2026

@mvanhorn is attempting to deploy a commit to the Dotsystems 9999 Team on Vercel.

A member of the Team first needs to authorize it.

@dotsystemsdevs dotsystemsdevs merged commit 651ef94 into dotsystemsdevs:main Apr 27, 2026
1 of 2 checks passed
@dotsystemsdevs
Copy link
Copy Markdown
Owner

Tack @mvanhorn — clean MV3 setup, minimal permissions (only host_permissions för commitmentissues.dev), graceful fallback på SPA-navigation och API-fel. Mergat. 🪦

@mvanhorn
Copy link
Copy Markdown
Contributor Author

Tack själv! Glad it landed cleanly. 🪦

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chrome extension: tombstone badge on GitHub repo pages

2 participants