Context
apps/loopover-extension/manifest.json:14 matches the content script on both
https://github.com/*/*/pull/* and https://github.com/*/*/issues/*. content.js's
matchGitHubPageTarget() (lines 7-13) correctly classifies both URL shapes, including computing
{ kind: "issue", owner, repo, issueNumber } for an issue page — but the script's only decision point
(line 3: if (target?.kind === "pull_request") { mountOverlay(target); }) never branches on
"issue", and matchPullRequestTarget() (lines 15-19) explicitly discards issue targets
(if (target?.kind !== "pull_request") return null;). Confirmed there is also no backend support to
render an issue-context overlay even if the extension side were completed:
src/api/routes.ts has exactly one extension-facing PR-context route
(GET /v1/extension/pull-context, line 2144) and no issue-context equivalent. The practical effect
today: every GitHub issue page a maintainer opens (matching the manifest) loads and runs this content
script, fully classifies the page, and then silently does nothing — the extension's declared scope
(manifest match) does not match its actual behavior (issue pages: no-op).
Requirements
- Decide and implement one of the two concrete fixes below — do not leave the mismatch in place:
- Option A (narrow scope, the smaller/safer change): Remove
"https://github.com/*/*/issues/*" from manifest.json's content-script matches, and remove
matchGitHubPageTarget's now-fully-dead "issue" branch (or simplify it to a boolean
pull-request-or-not check), since nothing consumes it. This is the correct default absent a concrete
plan to build issue-overlay support — file a separate, explicit spec issue first if issue-overlay
support is actually wanted (per this repo's own "what's safe to unleash" convention: don't
presuppose an undecided scope expansion).
- Option B: If issue-overlay support is genuinely wanted, this is a maintainer/product-scope
decision (a new backend route, new overlay content, new options-page copy) — do not silently
half-build it; that decision belongs in a separate maintainer-only spec issue, not folded into
this bug fix.
- This issue's own Deliverables assume Option A (the narrow-scope fix) as the default, mechanical,
contributor-safe resolution; a maintainer can redirect to Option B in review if they'd rather use this
as the trigger for a real issue-overlay spec.
Deliverables
Test Coverage Requirements
apps/** is in vitest.config.ts's coverage.exclude; Codecov's patch gate doesn't apply
numerically, but test/unit/extension-content.test.ts must be updated and continue passing, with a
regression test asserting an issue-page URL no longer produces a match (or is explicitly out of scope).
Expected Outcome
manifest.json's declared content-script scope matches what the script actually does on every page it
runs on — no page where the extension unconditionally loads and classifies content while intentionally
doing nothing with the result.
Links & Resources
apps/loopover-extension/manifest.json:14, apps/loopover-extension/content.js:1-19,
src/api/routes.ts:2144 (the only extension pull-context route, confirming no issue-context backend
exists today).
Context
apps/loopover-extension/manifest.json:14matches the content script on bothhttps://github.com/*/*/pull/*andhttps://github.com/*/*/issues/*.content.js'smatchGitHubPageTarget()(lines 7-13) correctly classifies both URL shapes, including computing{ kind: "issue", owner, repo, issueNumber }for an issue page — but the script's only decision point(line 3:
if (target?.kind === "pull_request") { mountOverlay(target); }) never branches on"issue", andmatchPullRequestTarget()(lines 15-19) explicitly discards issue targets(
if (target?.kind !== "pull_request") return null;). Confirmed there is also no backend support torender an issue-context overlay even if the extension side were completed:
src/api/routes.tshas exactly one extension-facing PR-context route(
GET /v1/extension/pull-context, line 2144) and no issue-context equivalent. The practical effecttoday: every GitHub issue page a maintainer opens (matching the manifest) loads and runs this content
script, fully classifies the page, and then silently does nothing — the extension's declared scope
(manifest match) does not match its actual behavior (issue pages: no-op).
Requirements
"https://github.com/*/*/issues/*"frommanifest.json's content-scriptmatches, and removematchGitHubPageTarget's now-fully-dead"issue"branch (or simplify it to a booleanpull-request-or-not check), since nothing consumes it. This is the correct default absent a concrete
plan to build issue-overlay support — file a separate, explicit spec issue first if issue-overlay
support is actually wanted (per this repo's own "what's safe to unleash" convention: don't
presuppose an undecided scope expansion).
decision (a new backend route, new overlay content, new options-page copy) — do not silently
half-build it; that decision belongs in a separate
maintainer-onlyspec issue, not folded intothis bug fix.
contributor-safe resolution; a maintainer can redirect to Option B in review if they'd rather use this
as the trigger for a real issue-overlay spec.
Deliverables
manifest.json's content-scriptmatchesno longer includeshttps://github.com/*/*/issues/*matchGitHubPageTarget's"issue"classification branch is removed (ormatchGitHubPageTargetis simplified to only ever return a pull-request target or
null), and any now-dead code(
matchPullRequestTarget's discard-"issue"branch, ifmatchGitHubPageTargetno longerproduces one) is cleaned up to match
test/unit/extension-content.test.tsis updated to reflect the narrowed behavior (no morekind: "issue"assertions for URLs that are no longer in scope)Test Coverage Requirements
apps/**is invitest.config.ts'scoverage.exclude; Codecov's patch gate doesn't applynumerically, but
test/unit/extension-content.test.tsmust be updated and continue passing, with aregression test asserting an issue-page URL no longer produces a match (or is explicitly out of scope).
Expected Outcome
manifest.json's declared content-script scope matches what the script actually does on every page itruns on — no page where the extension unconditionally loads and classifies content while intentionally
doing nothing with the result.
Links & Resources
apps/loopover-extension/manifest.json:14,apps/loopover-extension/content.js:1-19,src/api/routes.ts:2144(the only extension pull-context route, confirming no issue-context backendexists today).