Find a beginner-friendly issue. Fork the repo. Set up the dev environment. Read through the codebase. Start working.
Then check the issue again and see a comment from 2 days ago: "Hey I'm working on this, should have a PR up soon."
Two hours wasted. Every single time.
The weird part? Almost every existing tool for finding open source issues - goodfirstissue.dev, up-for-grabs.net, codetriage - rely on static lists or periodic scrapes. They show you issues, but they don't show you the live status of whether someone is already quietly working on it right now.
So I built GitTrek to fix this.
The core problem: Silent Claiming
When a developer starts working on an issue, they often don't comment or ask for assignment. They just start. But they usually leave one of these "digital traces":
- PR Mentions: They mention the issue number in a PR description or commit message (
Fixes #847). - Linked Branches: They click "Create a branch for this issue" in GitHub's UI, then open a PR from that branch.
Both leave detectable events in GitHub's GraphQL API that most discovery tools never bother to check.
The two GraphQL events that make it work
GitHub's timelineItems field on issues exposes every event in an issue's history. Two specific types are the key:
CROSS_REFERENCED_EVENT - Fires when someone mentions the issue number (#847) in a PR or commit. The PR is the source of this event.
CONNECTED_EVENT - Fires when a branch linked to the issue becomes a pull request. In this event, the PR is the subject, not the source.
Pro Tip: This is a common GraphQL "gotcha."
sourcefor one,subjectfor the other. Mix them up, and you get null results with zero errors.
The Query
issue(number: $issueNumber) {
timelineItems(
first: 25,
itemTypes: [CROSS_REFERENCED_EVENT, CONNECTED_EVENT]
) {
nodes {
... on CrossReferencedEvent {
source {
... on PullRequest {
number
state # OPEN | CLOSED | MERGED
isDraft
}
}
}
... on ConnectedEvent {
subject {
... on PullRequest {
number
state
isDraft
}
}
}
}
}
linkedBranches(first: 3) {
totalCount
}
}
The Classification Logic
GitTrek uses this data to color-code your search results instantly:
| Status | Condition |
|---|---|
| 🔴 Active PR | Open non-draft PR exists — high competition |
| 🟡 Someone started | Draft PR linked — proceed carefully |
| 🟡 Branch exists | linkedBranches > 0, no PR yet — early signal |
| ✅ Safe to claim | No linked PRs or branches found |
High Performance: Running checks in parallel
Checking 20 issues means 21 total API calls (1 search + 20 status checks). To keep the UI snappy, GitTrek doesn't block the initial results. We display the issues immediately and then "hydrate" the competition status badges in parallel:
// Fetch fresh data from APIs in the background
// This ensures one badge failure doesn't block the entire dashboard
const settlements = await Promise.allSettled([
fetch(`/api/github/badges/pull-shark?username=${user}`).then(r => r.json()),
fetch(`/api/github/badges/starstruck?username=${user}`).then(r => r.json()),
// ... more badge checks
]);
// Safely extract results even if some failed
const [pullShark, starstruck, ...] = settlements.map(s =>
s.status === "fulfilled" ? s.value : null
);
// Apply fallback values for failed items
const psData = pullShark || { count: 0 };
I used Promise.allSettled instead of Promise.all for a reason: if one check fails (e.g., due to a repository permission issue or a single-item rate limit), the rest of your dashboard stays functional.
What else GitTrek does
Beyond "Ghost PR" detection, I built GitTrek to be a full companion for open-source growth:
- Repository Quality Gates: Filter by stars, forks, and whether the repo actually has a CONTRIBUTING.md.
- Live Achievement Tracking: Track your progress toward Pull Shark, Galaxy Brain, and YOLO badges using live GraphQL calculations.
The best part? It suggests a "Focus Mission". If you're only 2 PRs away from Gold Pull Shark, GitTrek will build a custom search query to help you find the exact issues needed to close that gap.
Try it out
GitTrek is free, open source, and requires no setup for browsing. You only need to connect your GitHub account if you want to track your personalized badge progress.
Live App: gittrek.vercel.app
Source Code: github.com/mahendra-shah/GitTrek
One question for you: Have you ever wasted time on
an issue that was already being worked on? How did you
handle it? Drop it in the comments - curious how common
this actually is.

Top comments (0)