Skip to content

costajohnt/oss-scout

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

159 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

oss-scout

oss-scout

Find open source issues personalized to your contribution history

npm downloads CI License Node 20+ Claude Code Plugin

Most issue finders search GitHub for good first issue labels and hand you a list. You could do that yourself in 30 seconds.

oss-scout is different. It knows which repos you've contributed to, which maintainers have merged your work before, and which projects are actively maintained. It searches strategically, vets every result, and tells you where your next PR has the highest chance of getting merged.

Getting Started

Prerequisites

  • Node.js 20+
  • GitHub CLIgh auth login (install) or set GITHUB_TOKEN env var

Install

npx @oss-scout/core setup    # configure (no install needed)
npx @oss-scout/core search   # find issues

Or install globally: npm install -g @oss-scout/core

First run

1. Configure your preferences:

$ oss-scout setup

🔧 oss-scout setup

Detecting GitHub username...
GitHub username [yourname]:
Preferred languages (or "any" for all) [any]: typescript, rust
Issue labels to search for [good first issue, help wanted]:
Difficulty scope (beginner, intermediate, advanced) [all]: beginner, intermediate
Minimum repo stars [50]: 100
Project categories (nonprofit, devtools, infrastructure, web-frameworks, data-ml, education) [none]: devtools
Repos to exclude (owner/repo, comma-separated, optional):

✅ Setup complete! Preferences saved.

2. Import your GitHub history (so the tool knows where you've contributed before):

$ oss-scout bootstrap

Imported 23 merged PRs, 4 closed PRs, 142 starred repos
Scored 8 repositories

3. Search for issues:

$ oss-scout search

Found 8 issue candidates:

  ✅ owner/repo#123 [92/100]
     Add timeout option to res.download()
     https://github.com/owner/repo/issues/123
     Repo: 9/10, 2 merged PRs

  ✅ org/project#456 [85/100]
     Support NO_COLOR in browser builds
     https://github.com/org/project/issues/456
     Repo: 8/10, 1 merged PRs

  ⚠️ user/library#789 [78/100]
     Add encoding option to execaNode
     https://github.com/user/library/issues/789

Results are automatically saved. View them later with oss-scout results.

How Search Works

oss-scout runs four search strategies in priority order:

Strategy Flag What it searches Why it matters
merged Phase 0 Repos where you have merged PRs Highest merge probability
starred Phase 1 Your GitHub starred repos Implicit interest
broad Phase 2 General label/language filtered Discovery
maintained Phase 3 Actively maintained repos by topic Exploration

Run all strategies (default), or pick specific ones:

oss-scout search --strategy merged           # only repos you've contributed to
oss-scout search --strategy starred,broad     # starred repos + general discovery
oss-scout search --strategy all               # all strategies (default)

Heavy strategies (broad, maintained) are automatically skipped when your GitHub API quota is low.

Why Not Just Search GitHub?

Feature Label search oss-scout
Personalized to your history No Yes — prioritizes repos you've contributed to
Checks if issue is claimed No Yes — scans comments for claim phrases
Checks for existing PRs No Yes — uses timeline API
Project health check No Yes — commit recency, stars, CONTRIBUTING.md
Viability scoring No Yes — 0-100 with transparent factors
Rate limit aware No Yes — adaptive budget, never wastes quota
Spam detection No Yes — filters label farming, templated titles

Vetting

Every issue candidate goes through 6 parallel checks:

Check What it detects Method
Existing PRs Someone already submitted a fix Timeline API
Claimed "I'm working on this" in comments Comment text scanning
Project health Is the repo active and maintained? Commit history, stars, forks
Clear requirements Can you actually implement this? Body analysis (steps, code blocks)
Contribution guidelines Branch naming, test framework, CLA CONTRIBUTING.md probing
Your merge history Have your PRs been merged here before? Search API (cached)

Vet a specific issue:

$ oss-scout vet https://github.com/owner/repo/issues/123

✅ owner/repo#123: APPROVE
   Add timeout option to res.download()

Reasons to approve:
  + Trusted project (2 PRs merged)
  + Clear requirements
  + Contribution guidelines found

Project health: Active
  Last commit: 2 days ago

Re-vet all saved results to check for staleness:

$ oss-scout vet-list --prune

  ✅ owner/repo#123 — still_available [92/100]
  🔒 user/library#789 — claimed [78/100]
  🔀 org/project#456 — has_pr [85/100]

🔔 Changes since last check (1):
  user/library#789: still_available → claimed

Summary: 5 available, 1 claimed, 1 has PR, 1 closed
Pruned 3 unavailable issues from saved results.

Each run records every saved result's status, so the next vet-list reports just what changed ("was available, now claimed"). The transitions are also in the --json envelope (transitions[]), so a scheduler can act on them without re-diffing.

Saved Results

Search results are automatically saved to ~/.oss-scout/state.json after each search. Results deduplicate across runs — if the same issue appears again, scores are updated but the first-seen date is preserved.

oss-scout results             # view saved results
oss-scout results --json      # structured JSON output
oss-scout results clear       # wipe saved results
oss-scout vet-list --prune    # re-vet and remove stale issues

Skip list

Skip issues you don't want to see again. Skipped issues are excluded from future search results and auto-expire after 90 days.

oss-scout skip add https://github.com/owner/repo/issues/123    # skip an issue
oss-scout skip list                                              # show skipped issues
oss-scout skip remove https://github.com/owner/repo/issues/123  # unskip
oss-scout skip clear                                             # clear all skips

Skipping an issue also removes it from saved results. When you skip an issue that was in your saved results, metadata (repo, title, number) is preserved in the skip entry for context.

Cross-machine sync with gist persistence

Enable gist persistence to sync your state (preferences, repo scores, PR history, saved results) across machines via a private GitHub gist:

oss-scout config set persistence gist

Your GitHub token needs the gist scope: gh auth refresh -s gist

State is automatically pushed to the gist after each search, vet-list, or bootstrap. When you run oss-scout on a different machine, it finds the gist and pulls the latest state.

Configuration

Interactive setup

oss-scout setup    # first-run interactive configuration

View and update individual settings

oss-scout config                                    # show all preferences
oss-scout config --json                             # JSON output
oss-scout config set languages "typescript,rust"    # set languages
oss-scout config set minStars 100                   # minimum repo stars
oss-scout config set includeDocIssues false          # exclude doc-only issues
oss-scout config set excludeRepos "+spam/repo"       # append to exclude list
oss-scout config set excludeRepos -- "-spam/repo"   # remove ("--" escapes the dash)
oss-scout config reset                               # reset to defaults

All configuration options

Key Type Default Description
githubUsername string (detected) Your GitHub login; seeds personalization
languages string[] any (all languages) Programming language filter (use "any" for no filter)
labels string[] good first issue, help wanted Issue label filter
scope enum[] all Difficulty: beginner, intermediate, advanced
minStars number 50 Minimum repo star count
maxIssueAgeDays number 90 Skip issues older than this
includeDocIssues boolean true Include documentation-only issues
minRepoScoreThreshold number 4 Skip repos scoring below this (1-10)
excludeRepos string[] [] Repos to never search
excludeOrgs string[] [] Orgs to never search
aiPolicyBlocklist string[] matplotlib/matplotlib Repos with anti-AI policies
projectCategories enum[] [] Topic filter: devtools, web-frameworks, etc.
defaultStrategy enum[] all Default search strategies: merged, starred, broad, maintained
interPhaseDelayMs number 30000 Delay between search phases (rate-limit pacing)
broadPhaseDelayMs number 90000 Extra delay before the broad phase
skipBroadWhenSufficientResults number 8 Skip the broad phase once this many candidates are found (0 disables)
persistence enum local State storage: local or gist
preferLanguages string[] [] Soft-boost ranking for these repo languages (the --prefer-languages flag overrides)
preferRepos string[] [] Soft-boost ranking for these owner/repo slugs (the --prefer-repos flag overrides)
diversityRatio number 0 Fraction of result slots (0-1) reserved for unboosted candidates (the --diversity-ratio flag overrides)
slmTriageModel string (disabled) Ollama model id for local SLM pre-triage during vetting (e.g. gemma4:e4b); empty disables it
slmTriageHost string (127.0.0.1:11434) Override the Ollama HTTP host when it runs on another machine
featuresAnchorThreshold number 3 Min merged-PR count for a repo to be a features anchor (1-50)
featuresSplitRatio number 0.6 features quick-wins / bigger-bets split (0-1)

Install Options

CLI (recommended for individual use)

npm install -g @oss-scout/core
oss-scout setup
oss-scout bootstrap
oss-scout search

Claude Code Plugin

/plugin marketplace add costajohnt/oss-scout
/plugin install oss-scout@oss-scout

Restart Claude Code. Commands:

  • /scout — Multi-strategy issue search with interactive results
  • /scout-setup — Configure preferences

Agents (dispatched automatically by Claude):

  • issue-scout — Autonomous issue discovery and vetting
  • repo-evaluator — Repository health assessment before contributing

MCP Server (Cursor, Claude Desktop, Codex, Windsurf)

{
  "mcpServers": {
    "oss-scout": {
      "command": "npx",
      "args": ["@oss-scout/mcp@latest"]
    }
  }
}

Tools: search, scout-features, vet, skip, config, config-set, sync Resources: scout://config, scout://results, scout://scores

Scheduled digest (GitHub Action)

Run search on a schedule and open/update a digest issue in your repo with the top candidates. Copy examples/weekly-digest.yml into .github/workflows/ in your own repo:

on:
  schedule:
    - cron: "0 14 * * 1" # Mondays 14:00 UTC
permissions:
  issues: write
jobs:
  digest:
    runs-on: ubuntu-latest
    steps:
      - uses: costajohnt/oss-scout@v1
        with:
          github-username: your-github-login
          search-token: ${{ secrets.OSS_SCOUT_TOKEN }} # PAT for personalization (optional)

Inputs: github-username, search-token, issue-token, max-results, strategy, issue-title, issue-label, version. The action reuses the existing CLI (search + results --markdown); no extra machinery.

As a Library

npm install @oss-scout/core
import { createScout } from '@oss-scout/core';

const scout = await createScout({ githubToken: process.env.GITHUB_TOKEN });
const results = await scout.search({ maxResults: 10 });

for (const c of results.candidates) {
  console.log(`${c.issue.repo}#${c.issue.number}: ${c.viabilityScore}/100`);
}

Three persistence modes:

  • 'local' (default) — loads and saves ~/.oss-scout/state.json
  • 'gist' — oss-scout manages state via a private GitHub gist
  • 'provided' — caller owns the state object (for embedding in other tools)
// Host application provides and owns the state
const scout = await createScout({
  githubToken: token,
  persistence: 'provided',
  initialState: existingState,
});

// Record PR outcomes to improve future search quality
scout.recordMergedPR({ url, title, mergedAt, repo });
scout.recordClosedPR({ url, title, closedAt, repo });

// checkpoint() persists according to the mode: it writes local state in
// 'local' mode and pushes the gist in 'gist' mode. In 'provided' mode the
// caller owns persistence, so checkpoint() does not write — read scout.getState().
await scout.checkpoint();

Viability Scoring (0-100)

Factor Points Condition
Base 50 Always
Repo score +0 to +20 From 1-10 repo quality rating
Repo quality bonus +0 to +12 Stars and forks tiers
Merged PRs in repo +15 You've had PRs merged here
Clear requirements +15 Issue body has steps, code blocks, keywords
Fresh issue +0 to +15 Updated within 14 days (full), 15-30 days (partial)
Contribution guidelines +10 CONTRIBUTING.md found and parsed
Org affinity +5 Merged PRs in other repos under same org
Category match +5 Matches your preferred project categories
Existing PR -30 Someone already submitted a fix
Claimed -20 Someone commented they're working on it
Closed-without-merge history -15 Repo has rejected your PRs before (no merges)

Score is clamped to 0-100. Results sorted by: search priority > recommendation > score.

CLI Reference

oss-scout [--debug] <command> [--json]

Note: --debug is program-level; --json is a per-subcommand flag (it goes after
the command, e.g. `oss-scout search --json`, not `oss-scout --json search`).

Setup:
  setup                         Interactive first-run configuration
  bootstrap                     Import starred repos and PR history from GitHub
  sync                          Reconcile tracked open PRs (mark merged/closed)

Search:
  search [count]                Search for issues (default: 10)
    --strategy <s>              Strategies: merged,starred,broad,maintained,all
    --prefer-languages <list>   Soft-boost ranking for matching repo languages
    --prefer-repos <list>       Soft-boost ranking for these owner/repo slugs
    --diversity-ratio <n>       Reserve a fraction (0-1) of slots for unboosted
  features [count]              Feature opportunities in repos with 3+ merged PRs
    --anchor-threshold <n>      Override featuresAnchorThreshold (1-50)
    --split-ratio <r>           Override featuresSplitRatio (0-1)
    --broad                     Search across the ecosystem, not just anchors
  vet <issue-url>               Vet a specific issue
  vet-list                      Re-vet all saved results
    --prune                     Remove unavailable issues
    --concurrency <n>           Max parallel API requests (default: 5)

Results:
  results                       Show saved search results
    --markdown                  Render as a markdown table (for digests)
    --new-only                  Only results first seen since the last search
    --since <date>              Only results first seen at/after this date
  results clear                 Clear saved results

Skip:
  skip add <issue-url>          Skip an issue (exclude from searches)
  skip list                     Show all skipped issues
  skip remove <issue-url>       Unskip an issue
  skip clear                    Clear all skipped issues

Config:
  config                        Show current preferences
  config set <key> <value>      Update a preference
  config reset                  Reset to defaults

Global:
  --debug                       Debug logging
  --json                        Structured JSON output
  --version                     Show version

Spam Detection

Automatically filtered out:

  • Label farming — repos with 5+ beginner labels per issue
  • Templated titles — mass-created issues ("Add Question #42", "Add Question #43")
  • Anti-AI policies — repos in the aiPolicyBlocklist (configurable)

Architecture

@oss-scout/core
├── OssScout class          Public API, implements ScoutStateReader
├── IssueDiscovery          Multi-phase search orchestrator
├── IssueVetter             Parallel vetting pipeline
├── issue-eligibility       PR checks, claim detection, requirements analysis
├── issue-scoring           Viability scoring (pure functions)
├── issue-filtering         Spam detection, doc-only filtering, per-repo caps
├── anti-llm-policy         Detect repos with anti-AI contribution policies
├── feature-discovery       `scout features` anchor + broad discovery
├── personalization         preferLanguages/preferRepos boosts + diversity
├── linked-pr / roadmap     Stalled-PR detection, ROADMAP.md scraping
├── slm-triage              Optional local Ollama SLM pre-triage
├── search-phases           GitHub Search API helpers, caching, batching
├── search-budget           Rate limit tracking (30 req/min sliding window)
├── repo-health             Project health checks, CONTRIBUTING.md parsing
├── category-mapping        Project categories to GitHub topic mapping
├── http-cache              ETag response caching, in-flight deduplication
├── gist-state-store        Gist-backed persistence with conflict resolution
└── ScoutState (Zod)        Preferences, repo scores, PR history, saved results

License

MIT

Related

  • OSS Autopilot — full AI copilot for managing open source contributions (uses oss-scout for issue discovery)