| name | top-contributor-finder |
| description | Find and segment top external open-source contributors for relationship-building, weekly reporting, recognition, or contributor strategy. Use this whenever the user asks to identify "top contributors", "best OSS contributors", "contributors to thank", "who should we thank", "who is contributing meaningfully", "weekly top contributors", "contributor report", or asks for a GitHub contributor shortlist. This skill analyzes merged and open PRs, filters out employees/org members/bots and typo-only contributors, inspects open PR status for contributor-actionable concerns, enriches candidates with GitHub profile/repo context, and returns a practical contributor analysis with linked PRs/issues.
|
Top Contributor Finder
Identify external GitHub contributors who are doing meaningful work. The output can support simple relationship-building outreach, weekly Slack reports, recognition, contributor strategy, or ecosystem/partner discovery. This is not a formal contributor-program workflow.
Default target repo: your-org/your-repo.
When to use this skill
Use this skill when the user wants to:
- find top OSS contributors
- identify contributors for outreach, thank-you notes, or recognition
- create weekly top-contributor Slack reports
- produce recurring contributor recognition summaries
- understand which external contributors are doing meaningful work
- segment merged and open PR authors
- evaluate whether open PRs show contributor-actionable concerns, stale work, or low quality
- spot contributors who may also be maintainers, ecosystem partners, or relevant OSS builders
Core principles
- Prioritize meaningful contribution substance over raw PR count.
- Include open PRs as signal, but do not treat them as equivalent to merged work.
- Exclude bots, repo-owner employees, org members, and obvious internal contributors.
- Exclude typo-only, comment-only, formatting-only, and low-substance docs-only contributors from the top outreach list.
- Do not prioritize issue-only contributors unless the user explicitly asks for issue reporters.
- Keep the recommendation practical: who is contributing meaningfully, who merits outreach, who should be monitored, who should be skipped, and what the report/outreach implication is.
- Outreach framing should feel like “we noticed and appreciate you,” not “please join our program.”
Required tools and auth
Prefer the GitHub CLI:
gh auth status
The script writes generated JSON for the current analysis run. By default this goes under the system temp directory, not the repo:
/tmp/top-contributor-finder/<repo-owner>__<repo-name>/<generated-at>__<since>_to_<until>.json
Use --output when you want a specific disposable path. Use --output-dir only if the user explicitly asks to save the JSON somewhere else. Do not commit generated contributor JSON unless the user explicitly requests it.
Do not use --max-candidates for full top-contributor analysis unless the user explicitly wants a smaller sample; the default stores the full qualifying candidate set for that run.
Generated JSON shape
Each run produces JSON for the agent or human to inspect while writing the current report. Important top-level fields:
generated_at: UTC timestamp for the run
repo, since, until, excluded_orgs, and run_parameters: enough metadata to reproduce or compare the run
search_notes: GitHub Search totals and cap notes
candidate_count_before_limit, candidate_limit, and candidate_count: whether the run was limited
skipped_low_signal_logins: contributors skipped before expensive enrichment because they did not meet configured meaningful merged/open PR thresholds
run_parameters.min_meaningful_merged, run_parameters.min_meaningful_open, run_parameters.issue_activity_mode, and run_parameters.issue_activity_top_n: performance/scope knobs used for the run
contributor_rollups: compact per-contributor records for ranking cumulative top contributors and identifying recent activity from PR timestamps
candidates: full nested candidate details with profiles, PRs, issues, contributor-actionable concerns, normal open-PR states, and evidence
Use contributor_rollups for cumulative analysis because it is compact and easy to scan. It includes:
login
human_context.summary
human_context.contribution_themes
human_context.contribution_style
human_context.issue_vs_pr_activity
human_context.collaboration_signals
human_context.relationship_context
human_context.what_to_watch_next
recommended_action, such as outreach, monitor, or manual review; treat this as draft memory, not a final ranking
- supporting contribution counts
- first and last observed PR timestamps in the run
- merged/open/closed-unmerged PR numbers
- recent PR titles and URLs
open_pr_concern_summary for contributor-actionable open PR problems
open_pr_normal_state_summary for normal process states retained as metadata
Use candidates when writing the qualitative report or checking evidence. It keeps representative PRs/issues, recent comments/reviews, profile details, and the same human_context fields. Treat numbers as supporting evidence, not the point of the generated JSON.
Stateless cumulative weekly model
Weekly reports should not depend on retained repo artifacts. Instead, run a cumulative analysis for the full relevant period every time, then use PR and issue dates inside the generated JSON to understand what changed recently.
For , the default cumulative period starts at your project's launch or open-source date and ends at the report date. For other repos, use the full relevant OSS period or a broad enough date window to represent top contributors overall.
Use the current cumulative run to classify contributors roughly as:
newly important: the contributor appears to have crossed into top-contributor territory recently based on the dates of their meaningful merged/open work
established and active: already has a strong cumulative record and also has meaningful recent activity
established but quiet: remains a top contributor overall but has little or no recent activity
monitor: has promising open or issue activity but does not yet stand out relative to the current cohort
For outreach, prefer contributors who stand out relative to the current cumulative cohort. Do not treat one or two meaningful merges as automatically sufficient; use merged PR counts as evidence in context with PR substance, issue activity, profile/ecosystem signals, and how active other contributors are in the same period.
The helper script uses gh api, gh pr view, and GitHub GraphQL via gh api graphql. If gh is unavailable, use GitHub web/API tools manually and follow the same analysis steps.
Do not log or hardcode tokens.
Default analysis scope
Use sensible defaults unless the user says otherwise:
- Repo:
your-org/your-repo
- Since date: your project's launch or open-source date for ; otherwise last 30 days
- Internal org exclusions: the repo owner org is excluded by default; add extra orgs only when the user explicitly identifies them as internal
- Include PRs that are:
- merged since the start date
- open and created or updated since the start date
- closed/unmerged if they provide useful quality or contributor-concern context
- Include linked issues plus authored/commented issues in the date window so the generated JSON can capture whether someone is PR-heavy, issue-heavy, helping with triage, or turning discussion into implementation.
Recommended workflow
Step 1: Collect candidate data
Run the bundled script from the repository root:
python3 .agents/skills/top-contributor-finder/scripts/find_top_contributors.py \
--repo your-org/your-repo \
--since <YYYY-MM-DD>
The script gathers:
- merged PRs
- open PRs
- closed-unmerged PRs
- GitHub profile details
- owned repositories
- recently contributed repositories
- open PR status, review decision, mergeability, checks, labels, linked issues, recent comments, and recent reviews
- authored and commented issues in the date window for top-ranked candidates by default
The script intentionally does cheap PR-title/state prefiltering before profile, detailed PR, and issue enrichment. Defaults require either 2 likely meaningful merged PRs or 2 likely meaningful open PRs before expensive enrichment. This keeps one-off low-signal contributors from making full runs slow. To broaden the net for a one-time historical audit, lower the thresholds and collect issues for all candidates:
python3 .agents/skills/top-contributor-finder/scripts/find_top_contributors.py \
--repo your-org/your-repo \
--since <YYYY-MM-DD> \
--min-meaningful-merged 1 \
--min-meaningful-open 1 \
--issue-activity-mode all
GitHub Search rate limits are waited and retried by default when the reset is within --max-rate-limit-wait-seconds (default one hour). Use --no-rate-limit-wait only for a quick smoke run where partial issue context is acceptable. If the script still times out, narrow the date scope and output size with:
python3 .agents/skills/top-contributor-finder/scripts/find_top_contributors.py \
--repo your-org/your-repo \
--since <YYYY-MM-DD> \
--until <YYYY-MM-DD> \
--max-candidates 40 \
--issue-activity-mode none
Use --exclude-org for any additional organization the user says should be treated as internal. The repo owner org is excluded by default.
Use --until YYYY-MM-DD when the user wants a bounded report period such as one week. Without it, the script analyzes through today.
Repo collaborator filtering (recommended)
By default (--exclude-repo-collaborators, on by default), the script fetches the full list of repo collaborators via /repos/{owner}/{repo}/collaborators before any PR analysis. This deterministically excludes all users with write/admin/maintain access — including those with private org membership that the per-user org membership API cannot see. This is the most reliable internal-contributor filter when the authenticated gh token has sufficient repo permissions.
To disable this behavior (e.g. for public repos where you lack collaborator list access), pass --no-exclude-repo-collaborators. The script will fall back to per-user org membership checks and profile/company/bio heuristics.
The excluded collaborators are recorded in the generated JSON under excluded_repo_collaborators and excluded_repo_collaborators_count.
GitHub may still hide private org membership for non-collaborator contributors unless the authenticated account can see it, so the script also filters visible org membership plus profile/company/bio hints as a secondary layer.
Example when the user names another extra internal org:
python3 .agents/skills/top-contributor-finder/scripts/find_top_contributors.py \
--repo your-org/your-repo \
--since <YYYY-MM-DD> \
--exclude-org another-internal-org
Step 2: Review automated ranking and prefiltering
Read the generated JSON and understand what the script included or skipped before doing deeper evaluation. This step is about checking the automated triage, not making the final recommendation.
Useful fields include:
human_context.summary: one-sentence summary of what the contributor appears to be doing
human_context.contribution_themes: inferred areas such as core features, integrations, platform support, security/privacy, docs/tooling, or UI polish
human_context.contribution_style: whether the contributor is merged-PR heavy, open-PR heavy, issue-discussion heavy, or mostly low-substance so far
human_context.issue_vs_pr_activity: supporting counts and a plain-language issue-vs-PR read
human_context.collaboration_signals: contributor-actionable signals such as requested changes, failing checks, merge conflicts, CLA identity issues, or issue-readiness guidance
human_context.relationship_context: profile/repo/ecosystem hints useful for outreach or partnership context
human_context.what_to_watch_next: weekly follow-up prompts, such as whether open PRs landed or whether issue discussion turned into implementation
recommended_action: the script's draft action category (outreach, monitor, or manual review), to confirm or revise after reviewing all evidence
cheap_prefilter_counts: the cheap merged/open signal used before expensive enrichment
skipped_low_signal_logins: contributors skipped before expensive enrichment
issue_activity: representative authored/commented issues
open_pr_concern_summary: contributor-actionable open PR problems worth surfacing
open_pr_normal_state_summary: normal process states retained as metadata, such as review required or final review
open_pr_blocker_summary: raw/backcompat summary of inferred open PR states
inferred_blockers: per-PR state hints inferred from metadata, checks, and recent comments/reviews
search_notes: GitHub Search result counts and any cap/incompleteness notes
contributor_rollups: compact records intended for ranking cumulative top contributors and identifying recent activity from PR timestamps
Confirm that the defaults did not exclude a contributor the user explicitly cares about. If the user wants a broader audit, rerun with lower thresholds before making recommendations.
Step 3: Evaluate open PR concerns
For open PRs, surface only concerns that suggest the contributor may need guidance or needs to take action. The script keeps raw inferred_blockers, but report-writing should distinguish contributor-actionable concerns from normal repo process states.
Contributor-actionable concerns to surface:
- draft PR
- merge conflicts
- failing or incomplete checks
- changes requested
- issue not marked
ready-to-implement or ready-to-spec when the contributor appears to be outside the expected process
- CLA identity issue
Normal states to retain as metadata but not report as blockers by default:
- review required
- waiting for final review or merge
- manual testing proof, screenshots, or video requested as part of normal PR review
Open PRs are positive signal only when the contributor appears responsive and the work is meaningful. Do not frame normal maintainer review queues as a contributor problem.
Step 4: Review profile and ecosystem context
For each serious candidate, review:
- GitHub display name, bio, company, location, website, Twitter/X if present
- owned repositories with stars and descriptions
- organizations
- recent repositories contributed to
Look for relationship/partner signals:
- maintains a relevant OSS project
- contributes to relevant open-source ecosystems, frameworks, or developer tools in your product's space
- works at a relevant devtool, AI, infra, or open-source-friendly company
- has public projects that could become collaborator/grantee/sponsorship conversations later
Do not overstate profile findings. Say “potential signal” unless the profile clearly establishes maintainership or project ownership.
Step 5: Apply final human judgment
After reviewing PR evidence, issue activity, profile/ecosystem context, and the current contributor cohort, decide whether each candidate's draft recommended_action should stand or be revised. The script is a starting point; it cannot fully judge product importance, reviewer sentiment, whether a PR is strategically important, whether the contributor stands out relative to others this period, or whether relationship context changes the outreach priority.
Prefer contributors with:
- a meaningful merged track record that stands out relative to the current cohort
- fewer but deep PRs in strategic areas such as core features, integrations, platform support, i18n, security/privacy, or workflow reliability
- open PRs that are close to merge or clearly promising
- good review behavior: responds to feedback, rebases, clarifies scope
- profile/repo signals suggesting relevant product-space experience, OSS maintainership, or ecosystem credibility
Deprioritize contributors whose PRs are mostly:
- typo fixes
- comment-only cleanup
- formatting-only docs changes
- unmerged PRs with repeated unaddressed review feedback
- open-only activity that is not yet notable relative to the current cohort
For the final report, treat human_context and recommended_action as draft memory that should be refined with this full evidence review.
Report format
Use this structure:
Executive recommendation
State:
- recommended first outreach batch size
- who should be highlighted or contacted first
- who should be monitored briefly
- who should be skipped
Ranked contributor list
Use one ranked list rather than separate “strong outreach” and “watchlist” lists unless the user explicitly asks for separate buckets. For each candidate, include:
- GitHub handle with profile link
recommended_action from the generated JSON, with a short human explanation
- why they are ranked where they are
- strongest merged PRs with inline links, e.g.
[PR #<PR_ID>](https://github.com/your-org/your-repo/pull/<PR_ID>)
- open PRs with inline links and contributor-actionable concern only when there is one; omit normal review/final-review/manual-testing states from the main report
- profile/repo/ecosystem signal
Interpret recommended_action as draft memory only:
outreach: likely relationship-building candidate after final human judgment
monitor: visible signal worth keeping in the generated JSON for the current run, but the agent should decide whether it is notable enough to mention
manual review: passed thresholds but needs human judgment
Do not use action labels as the final ranking. Decide who counts as a top contributor by comparing contribution substance, merged/open activity, issue participation, profile/ecosystem context, and the strength of the current cohort.
Skip for this batch
List contributors excluded because they are internal, issue-only, typo-only, docs-only, not enough merged signal, or have unresolved contributor-actionable quality/process concerns.
Suggested outreach
Include this section only when the user wants outreach or relationship-building. Keep the action generic: recommend outreach, recognition, or a thank-you. Do not prescribe specific offers such as swag or credits unless the user asks.
Optional Slack thread to a report channel
Only post to Slack when the user explicitly asks to post or send the report. Do not create or rely on a dedicated Slack-posting script; the agent should decide the most valuable thread from the current generated JSON and post it directly using the available Slack credentials. Never print, echo, or store Slack tokens in plaintext.
Default destination: a configured report channel (e.g. #your-report-channel). Resolve the channel ID from available environment/configuration or Slack context before posting; if it cannot be resolved, ask the user for the channel ID rather than guessing. Use Slack mrkdwn and avoid accidental pings by formatting GitHub handles in backticks, e.g. @contributor_handle.
Weekly comparison approach
Before drafting the Slack thread, use the current cumulative generated JSON as the source of truth. Do not require previous artifacts. Identify recent changes from each contributor's PR and issue dates, especially mergedAt, createdAt, and updatedAt.
Use these practical groups for the Slack report:
- New or newly important top contributors: contributors who now stand out enough for the team to know about, especially if their meaningful activity is recent. Give these contributors full thread replies.
- Established and active top contributors: cumulative top contributors who also have meaningful recent work. Summarize them briefly; do not repeat the full profile every week.
- Established but quiet top contributors: cumulative top contributors with little or no recent activity. Surface them briefly only if the quiet period is useful context.
- Low-signal or unchanged contributors: omit them or group them in a very short parent-note count. Do not create thread replies for unchanged known contributors or low-signal open-only contributors.
Do not create a separate Slack category for “not outreach yet.” Do not include contributors merely because their open PRs have concerns. Open PR concerns can inform judgment, but the Slack report should focus on contributor relationship and repo-health signal, not PR triage.
Parent message
Keep the parent message concise and useful for teammates skimming Slack. Do not lead with analysis-window mechanics such as “since project launch,” “analysis period,” or “stateless cumulative run” unless the user explicitly asks for audit details. Include:
- repo being summarized
- 1-2 sentence summary of the most important contributor findings
- new/newly important top contributors worth knowing about
- established active top contributors in one short line
- established quiet top contributors, if useful
- suggested action, using generic wording such as
outreach, monitor, or no action
- a link to the agent session/conversation so teammates can continue the analysis with the agent
Thread replies
Create one thread reply per contributor only for contributors worth surfacing. Use full detail only for new or newly important top contributors. A full reply should include:
- GitHub handle and profile link
- why they matter now
- 1-3 strongest PR links
- concise contribution themes
- suggested action, usually
outreach or monitor
For established top contributors, use short replies only when there is meaningful recent activity. Otherwise mention them in the parent summary only when useful.
Posting mechanics
When posting is requested:
- Draft the parent message and thread replies first.
- Post the parent with Slack
chat.postMessage and capture its ts.
- Post each contributor reply with the same channel and
thread_ts set to the parent ts.
- Use
unfurl_links: false and unfurl_media: false.
- Include the agent session/conversation link in the parent message or final thread reply. Use a /<CLOUD_PRODUCT>-provided conversation or run link when available; do not fabricate a link. If no session link is available, say that instead of guessing.
- After posting, report the Slack permalink or parent timestamp to the user.
If posting fails partway through, tell the user which messages posted and which failed.
Quality checklist
Before finalizing:
- Every referenced PR or issue has an inline link.
- Merged and open PRs are clearly distinguished.
- Open PR concerns are described only when they are contributor-actionable and visible from GitHub.
- Internal contributors, bots, and org members are filtered out.
- Typo-only and issue-only contributors are not in the top outreach list.
- Profile/repo claims are grounded in GitHub profile data.
- Recommendations are concise enough to act on immediately.
Performance guidance
The slowest operations are, in order: detailed gh pr view calls for every PR search hit, GraphQL profile/repository enrichment for every contributor, org membership checks, and issue author/commenter searches. Avoid pulling all of those for contributors with only one likely meaningful merged PR and little or no open work unless the user explicitly wants an exhaustive audit. Contributor profile/internal checks and detailed PR enrichment run concurrently via --enrichment-workers (default 4; use 1 for serial execution). GitHub Search collection remains mostly sequential to avoid making Search rate limits worse. GitHub rate limits are waited and retried by default up to --max-rate-limit-wait-seconds; if the reset is beyond that, the generated JSON records the missing issue-search context in search_notes.
Validation
This skill does not bundle formal evals because the final output is judgment-heavy and depends on live GitHub state. Validate changes with a Python compile check, a small smoke run of the helper script, and qualitative review of the generated candidate output.