Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/README.skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Skills differ from other primitives by supporting bundled assets (scripts, code
| [refactor](../skills/refactor/SKILL.md) | Surgical code refactoring to improve maintainability without changing behavior. Covers extracting functions, renaming variables, breaking down god functions, improving type safety, eliminating code smells, and applying design patterns. Less drastic than repo-rebuilder; use for gradual improvements. | None |
| [scoutqa-test](../skills/scoutqa-test/SKILL.md) | This skill should be used when the user asks to "test this website", "run exploratory testing", "check for accessibility issues", "verify the login flow works", "find bugs on this page", or requests automated QA testing. Triggers on web application testing scenarios including smoke tests, accessibility audits, e-commerce flows, and user flow validation using ScoutQA CLI. IMPORTANT: Use this skill proactively after implementing web application features to verify they work correctly - don't wait for the user to ask for testing. | None |
| [snowflake-semanticview](../skills/snowflake-semanticview/SKILL.md) | Create, alter, and validate Snowflake semantic views using Snowflake CLI (snow). Use when asked to build or troubleshoot semantic views/semantic layer definitions with CREATE/ALTER SEMANTIC VIEW, to validate semantic-view DDL against Snowflake via CLI, or to guide Snowflake CLI installation and connection setup. | None |
| [sponsor-finder](../skills/sponsor-finder/SKILL.md) | Find which of a GitHub repository's dependencies are sponsorable via GitHub Sponsors. Uses deps.dev API for full dependency tree resolution (direct + transitive) across npm, PyPI, Cargo, Go, RubyGems, Maven, and NuGet. Checks npm funding metadata, FUNDING.yml files, and web search. Verifies every link before presenting. Includes OSSF Scorecard health data and actionable sponsor-count summaries. | None |
| [terraform-azurerm-set-diff-analyzer](../skills/terraform-azurerm-set-diff-analyzer/SKILL.md) | Analyze Terraform plan JSON output for AzureRM Provider to distinguish between false-positive diffs (order-only changes in Set-type attributes) and actual resource changes. Use when reviewing terraform plan output for Azure resources like Application Gateway, Load Balancer, Firewall, Front Door, NSG, and other resources with Set-type attributes that cause spurious diffs due to internal ordering changes. | `references/azurerm_set_attributes.json`<br />`references/azurerm_set_attributes.md`<br />`scripts/.gitignore`<br />`scripts/README.md`<br />`scripts/analyze_plan.py` |
| [vscode-ext-commands](../skills/vscode-ext-commands/SKILL.md) | Guidelines for contributing commands in VS Code extensions. Indicates naming convention, visibility, localization and other relevant attributes, following VS Code extension development guidelines, libraries and good practices | None |
| [vscode-ext-localization](../skills/vscode-ext-localization/SKILL.md) | Guidelines for proper localization of VS Code extensions, following VS Code extension development guidelines, libraries and good practices | None |
Expand Down
257 changes: 257 additions & 0 deletions skills/sponsor-finder/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
---
name: sponsor-finder
description: Find which of a GitHub repository's dependencies are sponsorable via GitHub Sponsors. Uses deps.dev API for dependency resolution across npm, PyPI, Cargo, Go, RubyGems, Maven, and NuGet. Checks npm funding metadata, FUNDING.yml files, and web search. Verifies every link. Shows direct and transitive dependencies with OSSF Scorecard health data. Invoke by providing a GitHub owner/repo (e.g. "find sponsorable dependencies in expressjs/express").
---

# Sponsor Finder

Find which of a repository's open source dependencies accept sponsorship via GitHub Sponsors (or Open Collective, Ko-fi, etc.). Accepts a GitHub `owner/repo`, uses the deps.dev API for dependency resolution and project health data, and produces a verified sponsorship report covering both direct and transitive dependencies.

## Your Workflow

When the user provides a repository in `owner/repo` format:

1. **Parse the input** β€” Extract `owner` and `repo`.
2. **Detect the ecosystem** β€” Fetch manifest to determine package name + version.
3. **Get full dependency tree** β€” deps.dev `GetDependencies` (one call).
4. **Resolve repos** β€” deps.dev `GetVersion` for each dep β†’ `relatedProjects` gives GitHub repo.
5. **Get project health** β€” deps.dev `GetProject` for unique repos β†’ OSSF Scorecard.
6. **Find funding links** β€” npm `funding` field, FUNDING.yml, web search fallback.
7. **Verify every link** β€” fetch each URL to confirm it's live.
8. **Group and report** β€” by funding destination, sorted by impact.

---

## Step 1: Detect Ecosystem and Package

Use `get_file_contents` to fetch the manifest from the target repo. Determine the ecosystem and extract the package name + latest version:

| File | Ecosystem | Package name from | Version from |
|------|-----------|-------------------|--------------|
| `package.json` | NPM | `name` field | `version` field |
| `requirements.txt` | PYPI | list of package names | use latest (omit version in deps.dev call) |
| `pyproject.toml` | PYPI | `[project.dependencies]` | use latest |
| `Cargo.toml` | CARGO | `[package] name` | `[package] version` |
| `go.mod` | GO | `module` path | extract from go.mod |
| `Gemfile` | RUBYGEMS | gem names | use latest |
| `pom.xml` | MAVEN | `groupId:artifactId` | `version` |

---

## Step 2: Get Full Dependency Tree (deps.dev)

**This is the key step.** Use `web_fetch` to call the deps.dev API:

```
https://api.deps.dev/v3/systems/{ECOSYSTEM}/packages/{PACKAGE}/versions/{VERSION}:dependencies
```

For example:
```
https://api.deps.dev/v3/systems/npm/packages/express/versions/5.2.1:dependencies
```

This returns a `nodes` array where each node has:
- `versionKey.name` β€” package name
- `versionKey.version` β€” resolved version
- `relation` β€” `"SELF"`, `"DIRECT"`, or `"INDIRECT"`

**This single call gives you the entire dependency tree** β€” both direct and transitive β€” with exact resolved versions. No need to parse lockfiles.

### URL encoding
Package names containing special characters must be percent-encoded:
- `@colors/colors` β†’ `%40colors%2Fcolors`
- Encode `@` as `%40`, `/` as `%2F`

### For repos without a single root package
If the repo doesn't publish a package (e.g., it's an app not a library), fall back to reading `package.json` dependencies directly and calling deps.dev `GetVersion` for each.

---

## Step 3: Resolve Each Dependency to a GitHub Repo (deps.dev)

For each dependency from the tree, call deps.dev `GetVersion`:

```
https://api.deps.dev/v3/systems/{ECOSYSTEM}/packages/{NAME}/versions/{VERSION}
```

From the response, extract:
- **`relatedProjects`** β†’ look for `relationType: "SOURCE_REPO"` β†’ `projectKey.id` gives `github.com/{owner}/{repo}`
- **`links`** β†’ look for `label: "SOURCE_REPO"` β†’ `url` field

This works across **all ecosystems** β€” npm, PyPI, Cargo, Go, RubyGems, Maven, NuGet β€” with the same field structure.

### Efficiency rules
- Process in batches of **10 at a time**.
- Deduplicate β€” multiple packages may map to the same repo.
- Skip deps where no GitHub project is found (count as "unresolvable").

---

## Step 4: Get Project Health Data (deps.dev)

For each unique GitHub repo, call deps.dev `GetProject`:

```
https://api.deps.dev/v3/projects/github.com%2F{owner}%2F{repo}
```

From the response, extract:
- **`scorecard.checks`** β†’ find the `"Maintained"` check β†’ `score` (0–10)
- **`starsCount`** β€” popularity indicator
- **`license`** β€” project license
- **`openIssuesCount`** β€” activity indicator

Use the Maintained score to label project health:
- Score 7–10 β†’ ⭐ Actively maintained
- Score 4–6 β†’ ⚠️ Partially maintained
- Score 0–3 β†’ πŸ’€ Possibly unmaintained

### Efficiency rules
- Only fetch for **unique repos** (not per-package).
- Process in batches of **10 at a time**.
- This step is optional β€” skip if rate-limited and note in output.

---

## Step 5: Find Funding Links

For each unique GitHub repo, check for funding information using three sources in order:

### 5a: npm `funding` field (npm ecosystem only)
Use `web_fetch` on `https://registry.npmjs.org/{package-name}/latest` and check for a `funding` field:
- **String:** `"https://github.com/sponsors/sindresorhus"` β†’ use as URL
- **Object:** `{"type": "opencollective", "url": "https://opencollective.com/express"}` β†’ use `url`
- **Array:** collect all URLs

### 5b: `.github/FUNDING.yml`
Use `get_file_contents` to fetch `{owner}/{repo}` path `.github/FUNDING.yml`.

Parse the YAML:
- `github: [username]` β†’ `https://github.com/sponsors/{username}`
- `open_collective: slug` β†’ `https://opencollective.com/{slug}`
- `ko_fi: username` β†’ `https://ko-fi.com/{username}`
- `patreon: username` β†’ `https://patreon.com/{username}`
- `tidelift: platform/package` β†’ `https://tidelift.com/subscription/pkg/{platform-package}`
- `custom: [urls]` β†’ use as-is

### 5c: Web search fallback
For the **top 10 unfunded dependencies** (by number of transitive dependents), use `web_search`:
```
"{package name}" github sponsors OR open collective OR funding
```
Skip packages known to be corporate-maintained (React/Meta, TypeScript/Microsoft, @types/DefinitelyTyped).

### Efficiency rules
- **Check 5a and 5b for all deps.** Only use 5c for top unfunded ones.
- Skip npm registry calls for non-npm ecosystems.
- Deduplicate repos β€” check each repo only once.

---

## Step 6: Verify Every Link (CRITICAL)

**Before including ANY funding link, verify it exists.**

Use `web_fetch` on each funding URL:
- **Valid page** β†’ βœ… Include
- **404 / "not found" / "not enrolled"** β†’ ❌ Exclude
- **Redirect to valid page** β†’ βœ… Include final URL

Verify in batches of **5 at a time**. Never present unverified links.

---

## Step 7: Output the Report

```
## πŸ’œ Sponsor Finder Report

**Repository:** {owner}/{repo}
**Scanned:** {current date}
**Ecosystem:** {ecosystem} Β· {package}@{version}

---

### Summary

- **{total}** total dependencies ({direct} direct + {transitive} transitive)
- **{resolved}** resolved to GitHub repos
- **πŸ’œ {sponsorable}** have verified funding links ({percentage}%)
- **{destinations}** unique funding destinations
- All links verified βœ…

---

### Verified Funding Links

| Dependency | Repo | Funding | Direct? | How Verified |
|------------|------|---------|---------|--------------|
| {name} | [{owner}/{repo}](https://github.com/{owner}/{repo}) | πŸ’œ [GitHub Sponsors](https://github.com/sponsors/{user}) | βœ… | FUNDING.yml |
| {name} | [{owner}/{repo}](https://github.com/{owner}/{repo}) | 🟠 [Open Collective](https://opencollective.com/{slug}) | ⛓️ | npm funding |
| ... | ... | ... | ... | ... |

Use βœ… for direct dependencies, ⛓️ for transitive.

---

### Funding Destinations (by impact)

| Destination | Deps | Health | Link |
|-------------|------|--------|------|
| 🟠 Open Collective: {name} | {N} direct | ⭐ Maintained | [opencollective.com/{name}](https://opencollective.com/{name}) |
| πŸ’œ @{user} | {N} direct + {M} transitive | ⭐ Maintained | [github.com/sponsors/{user}](https://github.com/sponsors/{user}) |
| ... | ... | ... | ... |

Sort by total number of dependencies (direct + transitive), descending.

---

### No Verified Funding Found

| Dependency | Repo | Why | Direct? |
|------------|------|-----|---------|
| {name} | {owner}/{repo} | Corporate (Meta) | βœ… |
| {name} | {owner}/{repo} | No FUNDING.yml or metadata | ⛓️ |
| ... | ... | ... | ... |

Only show the top 10 unfunded direct deps. If more, note "... and {N} more".

---

### πŸ’œ {percentage}% verified funding coverage Β· {destinations} destinations Β· {sponsorable} dependencies
### πŸ’‘ Sponsoring just {N} people/orgs covers all {sponsorable} funded dependencies
```

### Format notes
- **Direct?** column: βœ… = direct dependency, ⛓️ = transitive
- **Health** column: ⭐ Maintained (7+), ⚠️ Partial (4–6), πŸ’€ Low (0–3) β€” from OSSF Scorecard
- **How Verified**: `FUNDING.yml`, `npm funding`, `PyPI metadata`, `Web search`
- πŸ’œ GitHub Sponsors, 🟠 Open Collective, β˜• Ko-fi, πŸ”— Other
- Prioritize GitHub Sponsors links when multiple funding sources exist
- The **πŸ’‘ summary line** tells the user the minimum number of sponsorships to cover everything

---

## Error Handling

- If deps.dev returns 404 for the package β†’ fall back to reading the manifest directly and resolving via registry APIs.
- If deps.dev is rate-limited β†’ note partial results, continue with what was fetched.
- If `get_file_contents` returns 404 for the repo β†’ inform user repo may not exist or is private.
- If link verification fails β†’ exclude the link silently.
- Always produce a report even if partial β€” never fail silently.

---

## Critical Rules

1. **NEVER present unverified links.** Fetch every URL before showing it. 5 verified links > 20 guessed links.
2. **NEVER guess from training knowledge.** Always check β€” funding pages change over time.
3. **Be transparent.** Show "How Verified" and "Direct?" columns so users understand the data.
4. **Use deps.dev as primary resolver.** Fall back to registry APIs only if deps.dev is unavailable.
5. **Always use GitHub MCP tools** (`get_file_contents`), `web_fetch`, and `web_search` β€” never clone or shell out.
6. **Be efficient.** Batch API calls, deduplicate repos, respect sampling limits.
7. **Focus on GitHub Sponsors.** Most actionable platform β€” show others but prioritize GitHub.
8. **Deduplicate by maintainer.** Group to show real impact of sponsoring one person.
9. **Show the actionable minimum.** The πŸ’‘ line tells users the fewest sponsorships to cover all funded deps.
Loading