feat: implement hive github repo and discord as a connected game

This commit is contained in:
Timothy
2026-03-04 18:52:42 -08:00
parent 4b5ec796bc
commit 1c24848db3
13 changed files with 2156 additions and 0 deletions
@@ -0,0 +1,94 @@
name: Integration Bounty
description: A bounty task for the integration contribution program
title: "[Bounty]: "
labels: []
body:
- type: markdown
attributes:
value: |
## Integration Bounty
This issue is part of the [Integration Bounty Program](../../docs/integration-bounty-program.md).
**Claim this bounty** by commenting below — a maintainer will assign you within 24 hours.
- type: dropdown
id: bounty-type
attributes:
label: Bounty Type
options:
- "Smoke Test (10 pts)"
- "Agent Test Report (30 pts)"
- "Edge Case Report (15 pts)"
- "Write README (20 pts)"
- "Add Health Checker (25 pts)"
- "Add Health Check Endpoint (10 pts)"
- "Bug Fix (40 pts)"
- "Complete Promotion Checklist (50 pts)"
- "New Integration (75 pts)"
validations:
required: true
- type: dropdown
id: difficulty
attributes:
label: Difficulty
options:
- Easy
- Medium
- Hard
validations:
required: true
- type: input
id: tool-name
attributes:
label: Tool Name
description: The integration this bounty targets (e.g., `airtable`, `salesforce`)
placeholder: e.g., airtable
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
description: What needs to be done to complete this bounty.
placeholder: |
Describe the specific task, including:
- What the contributor needs to do
- Links to relevant files in the repo
- Any setup requirements (API keys, accounts, etc.)
validations:
required: true
- type: textarea
id: acceptance-criteria
attributes:
label: Acceptance Criteria
description: What "done" looks like. The PR or report must meet all criteria.
placeholder: |
- [ ] Criterion 1
- [ ] Criterion 2
- [ ] CI passes
validations:
required: true
- type: textarea
id: relevant-files
attributes:
label: Relevant Files
description: Links to tool directory, credential spec, health check file, etc.
placeholder: |
- Tool: `tools/src/aden_tools/tools/{tool_name}/`
- Credential spec: `tools/src/aden_tools/credentials/{category}.py`
- Health checks: `tools/src/aden_tools/credentials/health_check.py`
- type: textarea
id: resources
attributes:
label: Resources
description: Links to API docs, examples, or guides that will help the contributor.
placeholder: |
- [Building Tools Guide](../../tools/BUILDING_TOOLS.md)
- [Tool README Template](../../docs/templates/tool-readme-template.md)
- API docs: https://...
+37
View File
@@ -0,0 +1,37 @@
name: Bounty completed
description: Awards points and notifies Discord when a bounty PR is merged
on:
pull_request:
types: [closed]
jobs:
bounty-notify:
if: >
github.event.pull_request.merged == true &&
contains(join(github.event.pull_request.labels.*.name, ','), 'bounty:')
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
pull-requests: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Award XP and notify Discord
run: bun run scripts/bounty-tracker.ts notify
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
GITHUB_REPOSITORY_NAME: ${{ github.event.repository.name }}
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_BOUNTY_WEBHOOK_URL }}
LURKR_API_KEY: ${{ secrets.LURKR_API_KEY }}
LURKR_GUILD_ID: ${{ secrets.LURKR_GUILD_ID }}
PR_NUMBER: ${{ github.event.pull_request.number }}
+40
View File
@@ -0,0 +1,40 @@
name: Weekly bounty leaderboard
description: Posts the integration bounty leaderboard to Discord every Monday
on:
schedule:
# Every Monday at 9:00 UTC
- cron: "0 9 * * 1"
workflow_dispatch:
inputs:
since_date:
description: "Only count PRs merged after this date (YYYY-MM-DD). Leave empty for all-time."
required: false
jobs:
leaderboard:
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
pull-requests: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Post leaderboard to Discord
run: bun run scripts/bounty-tracker.ts leaderboard
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
GITHUB_REPOSITORY_NAME: ${{ github.event.repository.name }}
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_BOUNTY_WEBHOOK_URL }}
LURKR_API_KEY: ${{ secrets.LURKR_API_KEY }}
LURKR_GUILD_ID: ${{ secrets.LURKR_GUILD_ID }}
SINCE_DATE: ${{ github.event.inputs.since_date || '' }}
+24
View File
@@ -0,0 +1,24 @@
# Identity mapping: GitHub username -> Discord ID
#
# This file links GitHub accounts to Discord accounts for the
# Integration Bounty Program. When a bounty PR is merged, the
# GitHub Action uses this file to ping the contributor on Discord.
#
# HOW TO ADD YOURSELF:
# 1. Fork this repo
# 2. Add your entry below (keep alphabetical order)
# 3. Submit a PR with title: "docs: link @your-github to Discord"
#
# To find your Discord ID:
# 1. Open Discord Settings > Advanced > Enable Developer Mode
# 2. Right-click your name > Copy User ID
#
# Format:
# - github: your-github-username
# discord: "your-discord-id" # quotes required (it's a number)
# name: Your Display Name # optional
contributors:
# - github: example-user
# discord: "123456789012345678"
# name: Example User
+255
View File
@@ -0,0 +1,255 @@
# Contributor Guide — Integration Bounty Program
Welcome. This is a program where you earn XP, Discord roles, and eventually real money by testing and building integrations for the Aden agent framework.
## How It Works
1. You pick a bounty from the [GitHub issues board](https://github.com/adenhq/hive/issues?q=is%3Aissue+is%3Aopen+label%3A%22bounty%3A*%22)
2. You claim it by commenting on the issue
3. You do the work and submit a PR (or test report)
4. A maintainer reviews and merges
5. You automatically get XP in Discord via Lurkr, and your level goes up
6. At certain levels, you unlock roles. At the top tier, you unlock paid bounties.
## Getting Started (10 min)
### 1. Link your GitHub and Discord
Fork this repo and add yourself to `contributors.yml`:
```yaml
contributors:
# ... existing entries
- github: your-github-username
discord: "your-discord-id"
name: Your Name
```
To find your Discord ID:
1. Open Discord Settings > Advanced > Enable **Developer Mode**
2. Right-click your name in any channel > **Copy User ID**
Submit this as a PR with title: `docs: link @your-github to Discord`
**Why this matters:** Without this link, you'll still get points tracked, but Lurkr can't push XP to your Discord account and you won't get role upgrades or pings.
### 2. Join the Discord channels
- `#integrations-announcements` — Bounty postings, leaderboard, promotions
- `#integrations-testing` — Coordinate with other testers
- `#integrations-help` — Ask questions about tools, credentials, setup
- `#integration-showcase` — Show off what you built
### 3. Pick your first bounty
Filter GitHub issues by label:
- [`bounty:docs`](https://github.com/adenhq/hive/issues?q=is%3Aissue+is%3Aopen+label%3A%22bounty%3Adocs%22) — Write a README for a tool (20 pts, easiest)
- [`bounty:smoke-test`](https://github.com/adenhq/hive/issues?q=is%3Aissue+is%3Aopen+label%3A%22bounty%3Asmoke-test%22) — Test a tool with a real API key (10 pts)
- [`difficulty:easy`](https://github.com/adenhq/hive/issues?q=is%3Aissue+is%3Aopen+label%3A%22difficulty%3Aeasy%22) — All easy bounties
Comment on the issue: "I'd like to work on this" and wait for a maintainer to assign you (usually within 24 hours).
## Tiers
| Tier | How to Reach | What You Get |
|------|-------------|--------------|
| **Agent Builder** | ~500 XP (Lurkr level 5) | Discord role, bounty board access |
| **Open Source Contributor** | ~2,000 XP (Lurkr level 15) | Discord role, name in CONTRIBUTORS.md and tool READMEs |
| **Core Contributor** | Maintainer nomination | Dollar values on bounties, paid per completion |
Lurkr auto-assigns the first two roles when you hit the level. Core Contributor requires sustained, high-quality contributions and a maintainer vouching for you.
### How XP Adds Up
You earn XP from two sources:
| Source | How |
|--------|-----|
| **GitHub bounties** | Merge a PR with a `bounty:*` label — auto-pushed to Lurkr |
| **Discord activity** | Messages in `#integrations-*` channels, helping others, voice chat |
Both feed into the same Lurkr level. Helping people in Discord AND doing bounties levels you up faster than either alone.
## Bounty Types
### Smoke Test (10 pts)
**What:** Run an unverified tool with a real API key and report if it works.
**How:**
1. Pick a tool from the bounty board
2. Get an API key for that service (the bounty issue links to the help URL)
3. Set the environment variable: `export TOOL_API_KEY=your-key`
4. Run the tool functions and note what happens
5. Comment on the bounty issue with your results: pass/fail, any errors, logs
**Difficulty:** Easy. You don't need to write code, just test and report.
### Agent Test Report (30 pts)
**What:** Build a real agent that uses an unverified tool and document the experience.
**How:**
1. Pick a tool from the bounty board
2. Build a simple agent that uses the tool (see [Building Agents Guide](../tools/BUILDING_TOOLS.md))
3. Run the agent with a real task
4. Fill out the [test report template](templates/agent-test-report-template.md)
5. Submit the report as a comment on the bounty issue, or as a file in a PR
**What to include:** Environment, credential setup, which functions you tested, what worked, what broke, edge cases found, and logs or session ID.
**Difficulty:** Medium. Requires an API key and some familiarity with the framework.
### Write README (20 pts)
**What:** Write documentation for a tool that's missing its README.
**How:**
1. Pick a tool from the bounty board
2. Read the tool's source code in `tools/src/aden_tools/tools/{tool_name}/`
3. Read the credential spec in `tools/src/aden_tools/credentials/`
4. Fill in the [tool README template](templates/tool-readme-template.md)
5. Submit a PR adding `README.md` to the tool directory
**Quality bar:** Function names must match the actual code. Setup instructions must be accurate. API URLs must be real.
**Difficulty:** Easy. Good first bounty — you learn the codebase by reading and documenting it.
### Add Health Checker (25 pts)
**What:** Implement a credential health check so the system can validate API keys at startup.
**How:**
1. Pick a tool from the bounty board
2. Find a lightweight API endpoint that validates the credential (GET, no writes, no charges)
3. Add `health_check_endpoint` to the tool's CredentialSpec
4. Implement a HealthChecker class in `tools/src/aden_tools/credentials/health_check.py`
5. Register it in the `HEALTH_CHECKERS` dict
6. Run `uv run pytest tools/tests/test_credential_registry.py` to verify wiring
7. Submit a PR
**Difficulty:** Medium. Requires reading the service's API docs to find the right endpoint.
### Bug Fix (40 pts)
**What:** Find a bug during testing and fix it.
**How:**
1. Find a bug while doing a smoke test or agent test
2. File an issue describing the bug (or comment on the existing bounty issue)
3. Fix the bug in a PR
4. Add a test that covers the specific bug
5. Reference the bounty issue in your PR
**Difficulty:** Varies. The bug itself tells you the difficulty.
### New Integration (75 pts)
**What:** Build a complete new integration from scratch.
**How:**
1. Check the [Integration Request issues](https://github.com/adenhq/hive/issues?q=is%3Aissue+is%3Aopen+label%3A%22Integration%22) for requested integrations
2. Follow the [BUILDING_TOOLS.md](../tools/BUILDING_TOOLS.md) guide
3. Create: tool implementation + credential spec + health checker + tests + README
4. Register in `_register_unverified()` in `tools/__init__.py`
5. Run `make check && make test`
6. Submit a PR
**Difficulty:** Hard. This is a significant contribution — expect multiple review rounds.
### Complete Promotion Checklist (50 pts)
**What:** Take an unverified tool through the full [promotion checklist](integration-promotion-checklist.md) to make it verified.
**How:**
1. Pick a tool that has most checklist items already done (docs, health check, tests)
2. Complete the remaining items
3. Get at least 1 community test report (coordinate in `#integrations-testing`)
4. Submit a PR that moves the tool from `_register_unverified()` to `_register_verified()`
5. Include links to all checklist evidence in the PR description
**Difficulty:** Hard. Requires coordination and thoroughness.
## Achievement Badges
Permanent Discord roles earned through specific accomplishments:
| Badge | How to Earn |
|-------|-------------|
| **First Blood** | Complete your first bounty of any type |
| **Bug Hunter** | Fix 3 bugs found during testing |
| **Docs Champion** | Write 5 tool READMEs |
| **Health Inspector** | Add 5 health checkers |
| **Promoter** | Promote a tool from unverified to verified |
| **Full Stack** | Complete at least 1 bounty of every type |
| **Ironman** | 8 consecutive weeks with at least 1 bounty completion |
Badges are assigned by maintainers when you qualify. If you think you've earned one and it hasn't been assigned, ask in `#integrations-help`.
## Streaks
Consecutive weeks with at least one bounty completion earns XP multipliers:
| Streak | Multiplier |
|--------|-----------|
| 2 weeks | 1.1x |
| 4 weeks | 1.25x |
| 8+ weeks | 1.5x |
Missing a week resets the streak. A 20-point README bounty at an 8-week streak earns 30 XP instead of 20.
## Leaderboard
Posted every Monday at 9:00 UTC in `#integrations-announcements`. Top 3 get medal emojis.
You can also check your rank anytime in Discord:
```
/rank
```
Or view the web leaderboard via Lurkr's dashboard.
## Rules
1. **Claim before you start** — comment on the issue, wait to be assigned
2. **One person per bounty** — first to claim and get assigned gets it
3. **7-day window** — if you don't submit a PR within 7 days of being assigned, the bounty is unassigned and re-opened
4. **Maximum 3 active claims** — don't hoard bounties
5. **Quality matters** — PRs must pass CI, follow templates, and address review feedback
6. **No self-review** — you can't review your own PR
7. **Honest testing** — report failures, not just successes. Finding bugs is valuable
8. **No AI-only submissions** — AI tools are fine for assistance, but you must verify that function names, API URLs, and behavior match reality
## FAQ
**Q: Do I need an API key for every tool I test?**
A: Yes, for smoke tests and agent tests. Most services have free tiers. The bounty issue links to where you get the key.
**Q: Can I work on multiple bounties at once?**
A: Yes, up to 3 active claims at a time.
**Q: What if I find a bug but can't fix it?**
A: File an issue! Someone else can pick up the `bounty:bug-fix`. Finding bugs during testing is the whole point.
**Q: How do I become a Core Contributor?**
A: Keep contributing consistently across different bounty types for 4+ weeks. Maintainers will notice and nominate you when you're ready. There's no application process — just keep shipping quality work.
**Q: What if I haven't linked my Discord yet?**
A: You'll still be recognized in the GitHub Action logs and Discord webhook message, but Lurkr can't push XP to your account. Link your Discord ID in `contributors.yml` to start earning XP and roles.
**Q: Do I earn XP from Discord messages too?**
A: Yes. Lurkr awards XP for messages in `#integrations-*` channels (with a 60-second cooldown). Helping others in `#integrations-help` earns 2x XP. Both Discord XP and GitHub bounty XP feed into the same level.
## Quick Reference
| What | Where |
|------|-------|
| Bounty board | [GitHub Issues with bounty label](https://github.com/adenhq/hive/issues?q=is%3Aissue+is%3Aopen+label%3A%22bounty%3A*%22) |
| README template | [docs/templates/tool-readme-template.md](templates/tool-readme-template.md) |
| Test report template | [docs/templates/agent-test-report-template.md](templates/agent-test-report-template.md) |
| Promotion checklist | [docs/integration-promotion-checklist.md](integration-promotion-checklist.md) |
| Building tools guide | [tools/BUILDING_TOOLS.md](../tools/BUILDING_TOOLS.md) |
| Contributing guide | [CONTRIBUTING.md](../CONTRIBUTING.md) |
| Discord | [Join](https://discord.com/invite/MXE49hrKDk) |
| Your rank | Type `/rank` in Discord |
| Link your accounts | Add yourself to [contributors.yml](../contributors.yml) |
+269
View File
@@ -0,0 +1,269 @@
# Game Master Manual
Operations guide for maintainers running the Integration Bounty Program. This covers the day-to-day decisions: posting bounties, approving work, awarding points, managing tiers, and keeping the program healthy.
## Your Role
As a game master (maintainer), you:
- Post bounty issues and set dollar values for Core Contributors
- Assign claimed bounties to contributors
- Review and merge bounty PRs (which auto-triggers point/XP awards)
- Manually assign achievement badges and the Core Contributor role
- Monitor for gaming and low-quality submissions
- Keep the bounty board fresh and the community engaged
## Daily Operations
### Handling Bounty Claims
When someone comments "I'd like to work on this" on a bounty issue:
1. Check their GitHub profile — do they have relevant experience?
2. For `difficulty:easy` bounties, assign immediately (within 24 hours)
3. For `difficulty:medium` and `difficulty:hard`, check if they've completed easier bounties first
4. Assign the issue to them via GitHub
5. If they don't submit a PR within 7 days, unassign and re-open
### Reviewing Bounty PRs
When a bounty PR is submitted:
1. **Verify the PR matches the bounty** — does it actually complete what the issue asked for?
2. **Check quality gates** (see below)
3. **A different maintainer** must approve than the one who created the bounty issue
4. **Apply the correct `bounty:*` label** to the PR before merging (if not already present)
5. **Merge** — the GitHub Action automatically awards XP and posts to Discord
6. **Close the linked bounty issue**
### Quality Gate Checks
#### For `bounty:docs` (READMEs):
- [ ] Follows the [tool README template](templates/tool-readme-template.md)
- [ ] Setup instructions are accurate (API key URL works, steps are correct)
- [ ] Tool table lists all functions with correct names
- [ ] At least one usage example per tool function
- [ ] API reference link is valid
- [ ] Not obviously AI-generated without verification (check that API URLs and function names match reality)
#### For `bounty:health-check`:
- [ ] `health_check_endpoint` added to CredentialSpec
- [ ] HealthChecker class implemented with proper 200/401/429 handling
- [ ] Registered in `HEALTH_CHECKERS` dict
- [ ] `uv run pytest tools/tests/test_credential_registry.py` passes
- [ ] Endpoint is actually a lightweight validation call (no writes, no charges)
#### For `bounty:agent-test`:
- [ ] Test report follows the [template](templates/agent-test-report-template.md)
- [ ] Includes reproducible evidence (logs, session ID, or screenshots)
- [ ] Tests were done with a real API key, not mocked
- [ ] Reports both successes and failures honestly
- [ ] Edge cases section is filled out (even if "none found")
#### For `bounty:bug-fix`:
- [ ] Bug was found during actual integration testing (not invented)
- [ ] Fix addresses the root cause, not just the symptom
- [ ] Existing tests still pass
- [ ] New test added for the specific bug
#### For `bounty:new-tool`:
- [ ] Full implementation: tool + credential spec + tests + README
- [ ] Follows [BUILDING_TOOLS.md](../tools/BUILDING_TOOLS.md) patterns
- [ ] `make check && make test` passes
- [ ] Registered in `_register_unverified()` (not verified — needs community testing first)
#### For `bounty:promote`:
- [ ] Every item on the [promotion checklist](integration-promotion-checklist.md) is checked
- [ ] At least 1 community agent test report exists
- [ ] Move registration from `_register_unverified()` to `_register_verified()`
### Rejecting Submissions
When quality is insufficient:
1. Leave a specific, constructive review comment — explain exactly what needs to change
2. Request changes on the PR (don't close it)
3. Give them 7 days to address feedback
4. If no response after 7 days, close the PR and unassign the bounty issue
**Never:**
- Reject without explanation
- Deduct points for good-faith attempts that need revision
- Merge low-quality work just to be nice — it degrades the codebase and the program's credibility
## Weekly Operations
### Monday: Leaderboard Day
The `weekly-leaderboard.yml` action auto-posts at 9:00 UTC every Monday. After it posts:
1. Check the leaderboard in `#integrations-announcements`
2. If anyone new entered the top 3, congratulate them in the channel
3. Review the bounty board — are there enough open bounties? Aim for 10+ unclaimed at all times
### Thursday: Bounty Refresh
Mid-week check:
1. Are any bounties stale (assigned >7 days, no PR)? Unassign them
2. Are any bounty types depleted? Post more
3. Check `#integrations-help` — are people asking questions that suggest missing documentation? That's a signal for new `bounty:docs` issues
## Tier Management
### Promoting to Agent Builder (Automatic)
Lurkr handles this via role reward at level 5. No action needed.
### Promoting to Open Source Contributor (Automatic)
Lurkr handles this via role reward at level 15. No action needed.
### Promoting to Core Contributor (Manual)
This is the most important decision you make. Core Contributor unlocks monetary rewards, so the bar must be high.
**When to promote:**
1. The contributor has been active for **4+ weeks**
2. They have contributions across **3+ bounty types** (not just one category)
3. Their PRs are consistently clean — they don't need multiple rounds of back-and-forth
4. They've demonstrated **technical depth** (not just documentation — they can fix bugs, add health checks, or build tools)
5. At least one maintainer is willing to vouch for them
**How to promote:**
1. Discuss with other maintainers in your private channel
2. If consensus, assign the Core Contributor role in Discord manually
3. Post an announcement in `#integrations-announcements`:
```
Welcome @username as a Core Contributor! They've [brief summary of contributions].
```
4. Add them to the `#bounty-payouts` channel
5. Brief them on how dollar-value bounties work (see below)
**When NOT to promote:**
- They only do easy bounties (all docs, no code)
- They've been active for less than 4 weeks
- Their PRs frequently need significant rework
- They show signs of gaming (splitting work, low-effort submissions)
### Demoting / Pausing Core Contributor
If a Core Contributor becomes inactive or their quality drops:
1. Reach out privately first — "Hey, noticed you've been less active, everything okay?"
2. If quality is the issue, provide specific feedback
3. If they're inactive for 8+ weeks, remove the Core Contributor role (they can earn it back)
4. Never demote publicly — handle it in DMs
## Monetary Bounties
### Setting Dollar Values
For each bounty issue, post the dollar value in `#bounty-payouts` (visible only to Core Contributors):
```
Bounty #1234: Write README for salesforce_tool — $15
Bounty #1235: Add health checker for jira — $25
Bounty #1236: Full promotion of notion_tool — $75
```
**Suggested dollar ranges:**
| Bounty Type | Dollar Range | Notes |
|-------------|-------------|-------|
| `bounty:docs` | $1020 | $10 for simple tools, $20 for complex ones |
| `bounty:health-check` | $1530 | $15 for simple GET, $30 for complex auth |
| `bounty:smoke-test` | $510 | Quick validation |
| `bounty:agent-test` | $2040 | Requires real API key and time |
| `bounty:bug-fix` | $2050 | Depends on complexity |
| `bounty:new-tool` | $50150 | Depends on integration complexity |
| `bounty:promote` | $50100 | Full checklist completion |
### Payout Process
1. Core Contributor completes bounty, PR is merged
2. Verify the work meets quality gates
3. Record the payout in `#bounty-payouts`:
```
PAID: @username — Bounty #1234 — $15 — [payment method/reference]
```
4. Process payment via your payment system (PayPal, Wise, crypto, etc.)
### Budget Management
- Set a monthly budget cap and communicate it
- When budget is tight, reduce dollar values rather than stopping bounties entirely
- Point values (XP) are always awarded regardless of budget — money is a bonus layer
## Achievement Badges
These are manually assigned when someone qualifies. Check periodically.
| Badge | Trigger | How to Verify |
|-------|---------|---------------|
| **First Blood** | First bounty completed | Check their first merged PR with `bounty:*` label |
| **Bug Hunter** | 3 `bounty:bug-fix` PRs merged | Search: `is:pr is:merged author:USERNAME label:bounty:bug-fix` |
| **Docs Champion** | 5 `bounty:docs` PRs merged | Search: `is:pr is:merged author:USERNAME label:bounty:docs` |
| **Health Inspector** | 5 `bounty:health-check` PRs merged | Search: `is:pr is:merged author:USERNAME label:bounty:health-check` |
| **Promoter** | 1 `bounty:promote` PR merged | Search: `is:pr is:merged author:USERNAME label:bounty:promote` |
| **Full Stack** | At least 1 PR with each bounty type | Check all 7 bounty labels |
| **Ironman** | 8 consecutive weeks with a bounty PR | Check merge dates — no gap > 7 days |
When assigning a badge:
1. Assign the role in Discord
2. Post in `#integrations-announcements`:
```
@username just earned the Bug Hunter badge! 3 bugs found and fixed.
```
## Anti-Gaming Playbook
### Signs of Gaming
| Pattern | What It Looks Like | Response |
|---------|-------------------|----------|
| **Splitting** | One README split into 3 PRs | Reject extras, warn contributor |
| **AI spam** | README with wrong function names, hallucinated APIs | Reject, explain why verification matters |
| **Claim hoarding** | Claiming 10 bounties, completing 1 | Unassign after 7 days, limit to 3 active claims |
| **Self-review** | Reviewing their own work under alt account | Ban both accounts |
| **Low-effort agent tests** | Test report with no logs, no session ID | Request revision with specific feedback |
### Responses
**First offense:** Warning via PR comment or DM. Be specific about what was wrong.
**Second offense:** 2-week bounty cooldown (they can still contribute, but no bounty labels are applied to their PRs).
**Third offense:** Permanent removal from the bounty program. Core Contributor role revoked if applicable.
Document all actions in a private maintainer thread for transparency.
## Keeping the Program Alive
### What Makes It Stale
- No new bounties for 2+ weeks
- Same 3 people on the leaderboard every week
- Bounties claimed but never completed
- Announcements channel goes quiet
### What Keeps It Fresh
- **New bounty types** — when the Doc Sprint is done, launch the Health Check Sprint
- **Sprint events** — "This week: double XP on agent tests"
- **Shoutouts** — highlight exceptional contributions in announcements
- **Showcase pins** — pin the best demos in `#integration-showcase`
- **Rising stars** — mention newcomers who are ramping up fast
- **Milestones** — "We just promoted the 10th tool to verified!"
### Metrics to Track
| Metric | Healthy Range | Alarm |
|--------|-------------|-------|
| Open unclaimed bounties | 1030 | < 5 (post more) or > 50 (too many, focus) |
| Active contributors (last 30 days) | 5+ | < 3 |
| Average days claim → PR | 37 | > 14 (bounties too hard or claims going stale) |
| Tools promoted (monthly) | 25 | 0 (investigate blockers) |
| Core Contributor count | 310 | > 15 (bar too low) or 0 (bar too high) |
+223
View File
@@ -0,0 +1,223 @@
# Integration Bounty Program — Setup Guide
Complete setup from zero to running. Estimated time: 30 minutes.
## Prerequisites
- Admin access to the GitHub repo
- Admin access to the Discord server
- `gh` CLI installed and authenticated
## Step 1: Create GitHub Labels (2 min)
```bash
./scripts/setup-bounty-labels.sh
```
This creates 10 labels: 7 bounty types (`bounty:smoke-test`, `bounty:agent-test`, `bounty:docs`, `bounty:health-check`, `bounty:bug-fix`, `bounty:new-tool`, `bounty:promote`) and 3 difficulty levels (`difficulty:easy`, `difficulty:medium`, `difficulty:hard`).
Verify at: `https://github.com/adenhq/hive/labels`
## Step 2: Create Discord Channels (5 min)
Create these channels (or rename existing ones):
```
Category: Integrations
#integrations-announcements (read-only for non-admins)
#integrations-testing
#integrations-help
#integration-showcase
Category: Private
#bounty-payouts (visible only to Core Contributor role)
```
**Channel permissions:**
- `#integrations-announcements`: Everyone can read, only bots + admins can post
- `#bounty-payouts`: Visible only to users with the Core Contributor role
- All others: open to everyone
## Step 3: Create Discord Roles (3 min)
Create these roles if they don't exist. Order matters — higher = more prestigious:
| Role | Color | Hoisted | Mentionable |
|------|-------|---------|-------------|
| Core Contributor | Gold `#F1C40F` | Yes | Yes |
| Open Source Contributor | Purple `#9B59B6` | Yes | No |
| Agent Builder | Green `#2ECC71` | Yes | No |
Achievement badge roles (optional, create as needed):
| Role | Color |
|------|-------|
| First Blood | Default |
| Bug Hunter | Red `#E74C3C` |
| Docs Champion | Yellow `#F39C12` |
| Health Inspector | Orange `#E67E22` |
| Promoter | Gold `#F1C40F` |
| Full Stack | Teal `#1ABC9C` |
| Ironman | Default |
## Step 4: Install and Configure Lurkr (10 min)
### 4a. Invite Lurkr
Go to https://lurkr.gg/ and invite the bot to your server. Grant it the permissions it requests (Manage Roles, Send Messages, etc).
### 4b. Enable Leveling
In any channel:
```
/levels enable
```
### 4c. Configure Message XP
```
/levels set-xp min:15 max:25
/levels set-cooldown seconds:60
```
### 4d. Set Channel XP Multipliers
Boost XP in channels where helping others matters:
```
/levels multiplier channel:#integrations-help multiplier:2
/levels multiplier channel:#integrations-testing multiplier:1.5
```
Disable XP in bot-only channels:
```
/levels ignore channel:#integrations-announcements
/levels ignore channel:#bounty-payouts
```
### 4e. Configure Role Rewards
```
/levels role-reward add level:5 role:@Agent Builder
/levels role-reward add level:15 role:@Open Source Contributor
```
Do NOT auto-assign Core Contributor — that's maintainer-only.
### 4f. Generate Lurkr API Key
1. Go to https://lurkr.gg/ and log in with Discord
2. Navigate to your profile / API settings
3. Click "Create API Key"
4. Select **Read/Write** (not read-only)
5. Copy the key — you'll need it in the next step
## Step 5: Create Discord Webhook (2 min)
1. Go to **Server Settings > Integrations > Webhooks**
2. Click **New Webhook**
3. Name it `Bounty Tracker`
4. Set the channel to `#integrations-announcements`
5. Copy the webhook URL
## Step 6: Add GitHub Repository Secrets (3 min)
Go to **Repo Settings > Secrets and variables > Actions > New repository secret** and add:
| Secret Name | Value |
|-------------|-------|
| `DISCORD_BOUNTY_WEBHOOK_URL` | The webhook URL from Step 5 |
| `LURKR_API_KEY` | The Lurkr API key from Step 4f |
| `LURKR_GUILD_ID` | Your Discord server ID* |
*To find server ID: Enable Developer Mode in Discord (Settings > Advanced), then right-click the server name > Copy Server ID.
## Step 7: Test the Pipeline (5 min)
### Test 1: Verify the script runs locally
```bash
GITHUB_TOKEN=$(gh auth token) \
GITHUB_REPOSITORY_OWNER=adenhq \
GITHUB_REPOSITORY_NAME=hive \
bun run scripts/bounty-tracker.ts leaderboard
```
Expected: `Found 0 merged bounty PRs` (or more if you already have bounty PRs).
### Test 2: Test a webhook notification
Create a test PR, add the `bounty:docs` and `difficulty:easy` labels, merge it, and verify:
- GitHub Action `Bounty completed` runs successfully
- A message appears in `#integrations-announcements`
- If the contributor is in `contributors.yml`, Lurkr XP is awarded
### Test 3: Verify Lurkr role rewards
Check that role rewards are configured:
```
/levels role-rewards
```
## Step 8: Seed the First Bounty Issues (ongoing)
Use the bounty issue template in GitHub to create issues. Start with the easiest batch:
### Phase 1 (Week 1): Documentation bounties
For each unverified tool missing a README, create an issue:
- Title: `[Bounty]: Write README for {tool_name}`
- Bounty type: `Write README (20 pts)`
- Difficulty: `Easy`
- Labels: `bounty:docs`, `difficulty:easy`
### Quick list of tools missing READMEs
```
azure_sql, cloudinary, confluence, databricks, docker_hub, duckduckgo,
google_search_console, google_sheets, greenhouse, jira, kafka, lusha,
mongodb, notion, obsidian, pagerduty, pinecone, pipedrive, plaid,
pushover, quickbooks, redshift, sap, salesforce, shopify, snowflake,
supabase, terraform, tines, trello, twilio, twitter, vercel,
yahoo_finance, zoom, huggingface, langfuse, microsoft_graph, n8n,
powerbi, redis
```
## Verification Checklist
After setup, verify everything works:
- [ ] Labels exist on the repo (`bounty:*` and `difficulty:*`)
- [ ] Discord channels created and permissions set
- [ ] Discord roles created in correct order
- [ ] Lurkr installed, leveling enabled, XP configured
- [ ] Lurkr role rewards set for levels 5 and 15
- [ ] Lurkr API key is Read/Write
- [ ] All 3 GitHub secrets added
- [ ] `bounty-completed.yml` workflow exists and is enabled
- [ ] `weekly-leaderboard.yml` workflow exists and is enabled
- [ ] Test PR + merge triggers notification in Discord
- [ ] `contributors.yml` exists at repo root
## Troubleshooting
**Action runs but no Discord message:**
- Check the `DISCORD_BOUNTY_WEBHOOK_URL` secret is set correctly
- Check the webhook channel still exists and the webhook hasn't been deleted
- Check the Action logs for error messages
**Lurkr XP not awarded:**
- Confirm `LURKR_API_KEY` and `LURKR_GUILD_ID` secrets are set
- Confirm the API key is Read/Write (not read-only)
- Confirm the contributor has linked their Discord ID in `contributors.yml`
- Check Action logs for `Lurkr XP push failed` messages
**Role not assigned after level up:**
- Verify role rewards are configured: `/levels role-rewards`
- Lurkr assigns roles on level-up, not retroactively. The user may need to send a message or run `/rank` to trigger it
- Verify Lurkr's role is above the roles it needs to assign in the server role hierarchy
**Weekly leaderboard not posting:**
- The cron schedule is Monday 9:00 UTC. Check that the workflow is enabled
- Manually trigger: Actions > Weekly bounty leaderboard > Run workflow
+372
View File
@@ -0,0 +1,372 @@
# Integration Bounty Program
Gamified contribution program for expanding and hardening Aden's integration ecosystem. Community members earn points by testing, documenting, and building integrations — with monetary rewards unlocked at the Core Contributor tier.
## Why Contribute?
### Visible Status
Every Discord message you send shows your tier role and badges. When someone asks a question in `#integrations-help` and you answer it with a **Core Contributor** badge, people listen. Your role is earned, not bought.
### Your Name in the Product
When you promote a tool to verified, your GitHub handle goes in the tool's README under `Contributed by`. Every agent that uses that integration carries your name. This is permanent credit in a production codebase — not a profile badge that disappears.
### Weekly Races
Every Monday the bot posts the leaderboard. The top 3 get medal emojis next to their name all week. There's a `#integration-showcase` channel where people demo agents using the tools they tested — the best demos get pinned and highlighted in announcements.
### The Path to Paid
Core Contributor unlocks real money. But you can't buy your way in — it takes sustained quality work across testing, docs, and code. The scarcity makes it matter. When you see someone with Core Contributor status, you know they've shipped real integrations.
### Streaks
Consecutive weeks with at least one bounty completion earns streak multipliers:
| Streak | Multiplier | Example |
|--------|-----------|---------|
| 2 weeks | 1.1x | 20pt README = 22 pts |
| 4 weeks | 1.25x | 30pt agent test = 37 pts |
| 8+ weeks | 1.5x | 75pt new tool = 112 pts |
Missing a week resets the streak. This rewards consistency over bursts.
### Achievement Badges
Unlocked permanently and displayed on your Discord profile via bot roles:
| Badge | Requirement | Role Color |
|-------|-------------|------------|
| **First Blood** | Complete your first bounty | — |
| **Bug Hunter** | Find and fix 3 bugs via testing | Red |
| **Docs Champion** | Write 5 tool READMEs | Yellow |
| **Health Inspector** | Add 5 health checkers | Orange |
| **Promoter** | Promote a tool from unverified to verified | Gold |
| **Full Stack** | Complete at least 1 bounty of every type | Rainbow |
| **Ironman** | 8-week contribution streak | — |
## Tiers
| Tier | How to Reach | What You See | Rewards |
|------|-------------|--------------|---------|
| **Agent Builder** | Join Discord + start testing | Bounty board with point values | Discord role, community recognition, achievement badges |
| **Open Source Contributor** | First merged PR | Bounty board with point values | Discord role, listed in CONTRIBUTORS.md, name in tool READMEs |
| **Core Contributor** | Maintainer-approved promotion | Bounty board with **dollar values** | Monetary payout per completed bounty, private dev channel |
### Core Contributor Promotion
Core Contributor status is **maintainer-approved** and requires:
1. **Sustained contribution** — consistent activity over multiple weeks, not a one-time burst
2. **Breadth** — contributions across multiple activity types (not just 20 READMEs)
3. **Quality** — history of clean PRs that pass CI without excessive back-and-forth
4. **Maintainer nomination** — at least one maintainer vouches for the contributor
Core Contributors see dollar values on bounty issues via a private Discord channel. Payouts happen per completed bounty after the PR is merged and approved by a maintainer.
## Point System
### Testing (Highest Priority)
These are the most valuable contributions — testing integrations with real API keys and real agents is the bottleneck for promoting tools from unverified to verified.
| Activity | Points | Requirements |
|----------|--------|-------------|
| **Smoke Test** | 10 | Run a tool with a real API key, submit a pass/fail report with logs |
| **Agent Test Report** | 30 | Build an agent using an unverified tool, submit a structured test report with session ID |
| **Edge Case Report** | 15 | Document a specific edge case (rate limits, auth expiry, malformed data, etc.) |
| **Live Demo** | 25 | Record a short video/GIF of an integration working in an agent |
### Code Contributions
| Activity | Points | Requirements |
|----------|--------|-------------|
| **Bug Fix PR** | 40 | Fix a bug found during testing, merged PR |
| **Add Health Checker** | 25 | Implement health check class + register in HEALTH_CHECKERS, merged PR |
| **Add health_check_endpoint** | 10 | Research correct endpoint, add to CredentialSpec, merged PR |
| **Write README** | 20 | Add missing README following the [tool README template](templates/tool-readme-template.md), merged PR |
| **Complete Promotion Checklist** | 50 | Finish all items on the [promotion checklist](integration-promotion-checklist.md) for a tool, merged PR |
| **New Integration** | 75 | Full implementation (tool + credential spec + tests + docs), merged PR |
### Community
| Activity | Points | Requirements |
|----------|--------|-------------|
| **PR Review** | 15 | Substantive code review on an integration PR (not just "LGTM") |
| **Help in Discord** | 5 | Answer an integration question (mod-verified) |
| **Propose Integration** | 5 | File a well-structured `[Integration]:` issue per existing template |
## Quality Gates
Points are only awarded after quality verification:
- **PRs**: Must be merged by a maintainer (not self-merged)
- **Test reports**: Must follow the [test report template](templates/agent-test-report-template.md) with reproducible evidence (logs, session ID, screenshots)
- **Health checkers**: Must pass CI (`uv run pytest tools/tests/test_credential_registry.py`)
- **READMEs**: Must follow the [tool README template](templates/tool-readme-template.md)
- **Reviews**: Must include actionable feedback, not just approval
- **Bounties are claimed before work starts** — comment on the issue to claim, wait for maintainer assignment
### Anti-Gaming Rules
- No self-review on PRs
- A different maintainer must approve bounty completion than the one who created it
- Duplicate or near-duplicate submissions are rejected
- Low-effort submissions (copy-pasted from AI without verification) are rejected and may result in point deduction
- Splitting a single change across multiple PRs to farm points is not allowed
## Bounty Issues
Integration bounties are tracked as GitHub Issues with specific labels.
### Labels
| Label | Color | Meaning |
|-------|-------|---------|
| `bounty:smoke-test` | `#0E8A16` (green) | Run tool with real API key, report results |
| `bounty:agent-test` | `#1D76DB` (blue) | Test tool in a real agent workflow |
| `bounty:docs` | `#FBCA04` (yellow) | Write or improve documentation |
| `bounty:health-check` | `#D93F0B` (orange) | Add health check endpoint or checker |
| `bounty:bug-fix` | `#B60205` (red) | Fix a discovered bug |
| `bounty:new-tool` | `#6F42C1` (purple) | Build a new integration from scratch |
| `bounty:promote` | `#C2A000` (gold) | Complete full promotion checklist |
| `difficulty:easy` | `#BFD4F2` | Good first contribution |
| `difficulty:medium` | `#D4C5F9` | Requires some familiarity |
| `difficulty:hard` | `#F9D0C4` | Significant effort or expertise needed |
### Bounty Issue Structure
Each bounty issue includes:
- **Activity type** (label)
- **Difficulty** (label)
- **Point value** (visible to all in issue body)
- **Dollar value** (visible only to Core Contributors via private Discord channel)
- **Acceptance criteria** (what "done" looks like)
- **Relevant files** (links to the tool directory, credential spec, etc.)
See the [bounty issue template](../.github/ISSUE_TEMPLATE/integration-bounty.yml) for the standard format.
## Discord Structure
```
#integrations-announcements — New bounties, tool promotions, leaderboard updates
#integrations-testing — Coordinate who's testing what, share test reports
#integrations-help — Get help with credential setup, tool development
#integration-showcase — Demos of agents using integrations
# Private (Core Contributors only)
#bounty-payouts — Dollar values, payout tracking, claims
```
## Leaderboard
Weekly leaderboard posted to `#integrations-announcements`:
- Top 10 contributors by points (rolling 30 days)
- Top 10 contributors all-time
- Recently promoted tools (unverified -> verified)
- Number of open bounties by type
Tracking is done via GitHub labels on merged PRs and closed issues. Maintainers tag completed work with the appropriate `bounty:*` label and contributor handle.
## Launch Plan: The 55-Tool Blitz
The initial launch targets the 55 unverified tools that need testing, documentation, and health checks.
### Phase 1: Doc Sprint (Week 1-2)
- Post 41 `bounty:docs` issues for tools missing READMEs
- `difficulty:easy`, 20 points each
- Provide the [tool README template](templates/tool-readme-template.md) so contributors fill in the blanks
### Phase 2: Health Check Sprint (Week 2-3)
- Post 40 `bounty:health-check` issues for tools missing health check endpoints
- `difficulty:medium`, 25 points each
- Provide example health checker code in each issue
### Phase 3: Agent Test Sprint (Week 3-5)
- Post 55 `bounty:agent-test` issues — one per unverified tool
- `difficulty:medium`, 30 points each
- Provide a template agent that contributors can swap their tool into
### Phase 4: Promotion Sprint (Week 5-8)
- Post `bounty:promote` issues for tools that have completed docs + health checks + testing
- `difficulty:hard`, 50 points each
- The contributor who completes the final checklist item gets the promotion bonus
- Each promoted tool gets an announcement in `#integrations-announcements`
## Automation
The bounty program runs on **GitHub Actions + Lurkr bot + Discord webhooks**. GitHub Actions calculate points from merged PRs, push XP to Lurkr via its API, and post notifications. Lurkr handles the Discord leveling, leaderboard display, and automatic role assignments.
### How It Works
```
PR merged with bounty:* label
→ GitHub Action fires bounty-tracker.ts
→ Script calculates points from label
→ Script resolves GitHub → Discord ID via contributors.yml
→ Script calls Lurkr API: PATCH /levels/{guild}/users/{user} (+XP)
→ Lurkr auto-assigns role rewards at XP thresholds
→ Script posts Discord webhook notification to #integrations-announcements
```
One system, one leaderboard, one set of roles. Discord activity XP and GitHub bounty XP flow into the same Lurkr leveling system.
### GitHub Actions
| Workflow | Trigger | What It Does |
|----------|---------|-------------|
| `bounty-completed.yml` | PR merged with `bounty:*` label | Calculates points, pushes XP to Lurkr, posts Discord notification |
| `weekly-leaderboard.yml` | Every Monday 9:00 UTC (or manual) | Generates leaderboard from all merged bounty PRs, posts to Discord |
Both use `scripts/bounty-tracker.ts` (Bun/TypeScript) which:
- Reads `bounty:*` labels from merged PRs to calculate points
- Resolves GitHub username → Discord ID via `contributors.yml`
- Calls Lurkr API to atomically increment XP: `PATCH /levels/{guildId}/users/{userId}` with `{"xp": {"increment": N}}`
- Posts formatted messages to Discord via webhook
### Lurkr Bot Setup
[Lurkr](https://lurkr.gg/) is a free, no-paywall leveling bot with a full REST API that accepts external XP pushes — the only major leveling bot that supports this.
#### 1. Invite Lurkr to your Discord server
Go to https://lurkr.gg/ and invite the bot.
#### 2. Enable leveling
```
/levels enable
```
#### 3. Configure XP for Discord activity
Lurkr will also award XP for regular Discord messages. Configure this so Discord engagement and GitHub bounties both feed into the same system:
- Set message XP range (e.g., 15-25 XP per message)
- Set cooldown (e.g., 60 seconds — prevents spam farming)
- Optionally boost XP in `#integrations-help` and `#integrations-testing` channels so helping others earns more
```
/levels set-xp min:15 max:25
/levels set-cooldown seconds:60
/levels multiplier channel:#integrations-help multiplier:2
/levels multiplier channel:#integrations-testing multiplier:1.5
```
#### 4. Configure role rewards
Map Lurkr levels to your existing Discord tiers. The XP thresholds should be calibrated so that a mix of Discord activity and GitHub bounties is needed to level up.
| Lurkr Level | XP Threshold | Discord Role | How to Reach |
|-------------|-------------|-------------|-------------|
| 5 | ~500 XP | **Agent Builder** | A few bounties or active Discord participation |
| 15 | ~2,000 XP | **Open Source Contributor** | Sustained bounty contributions |
| 30 | ~5,000 XP | Core Contributor *eligible* | Significant sustained contribution |
Note: **Core Contributor** role is still manually assigned by maintainers (since it involves money). Lurkr level 30 signals eligibility, not automatic promotion.
Add role rewards in the Lurkr dashboard or via commands:
```
/levels role-reward add level:5 role:@Agent Builder
/levels role-reward add level:15 role:@Open Source Contributor
```
Achievement badge roles (First Blood, Bug Hunter, etc.) are added manually by maintainers when someone qualifies — these are not level-based.
#### 5. Generate a Read/Write API key
- Go to https://lurkr.gg/ and log in
- Navigate to your profile / API settings
- Create a **Read/Write** API key (not read-only — we need PATCH access)
- Copy the key
#### 6. Add secrets to GitHub repository
Add three secrets in **Repo Settings > Secrets and variables > Actions**:
| Secret | Value |
|--------|-------|
| `DISCORD_BOUNTY_WEBHOOK_URL` | Discord webhook URL for `#integrations-announcements` |
| `LURKR_API_KEY` | Your Lurkr Read/Write API key |
| `LURKR_GUILD_ID` | Your Discord server ID |
To find your server ID: Enable Developer Mode in Discord (Settings > Advanced), then right-click the server name > Copy Server ID.
#### 7. Create the labels and start posting bounties
```bash
./scripts/setup-bounty-labels.sh
```
That's it. When a maintainer merges a PR with a `bounty:*` label, the contributor automatically gets:
- XP added to their Lurkr level
- A notification in `#integrations-announcements` with their new level
- Role upgrades when they cross level thresholds
### Identity Linking (GitHub ↔ Discord)
Contributors link their accounts by adding themselves to `contributors.yml` at the repo root:
```yaml
contributors:
- github: jane-doe
discord: "123456789012345678"
name: Jane Doe
```
This is intentionally a file-in-repo approach (not a database) because:
- It's version-controlled and auditable
- Adding yourself is a PR — which is itself a contribution
- No bot infrastructure needed for identity storage
- Maintainers can review and approve linkages
**To find your Discord ID:** Enable Developer Mode in Discord Settings > Advanced, then right-click your name > Copy User ID.
**Important:** Contributors who haven't linked their Discord ID in `contributors.yml` will still get bounty notifications on GitHub, but won't receive Lurkr XP or Discord pings. The notification will remind them to link.
### What Handles What
| Concern | Handled By | How |
|---------|-----------|-----|
| Bounty point calculation | GitHub Actions | `bounty-completed.yml` reads PR labels |
| XP push to Discord | GitHub Actions → Lurkr API | `PATCH /levels/{guild}/users/{user}` with `{"xp": {"increment": N}}` |
| Discord engagement XP | Lurkr bot | Native message XP (configurable per-channel) |
| Leaderboard | Lurkr bot | Built-in `/levels leaderboard` + web leaderboard |
| Weekly announcement | GitHub Actions | `weekly-leaderboard.yml` posts via webhook |
| Agent Builder role | Lurkr bot | Auto-assigned at level 5 via role reward |
| OSS Contributor role | Lurkr bot | Auto-assigned at level 15 via role reward |
| Core Contributor role | Maintainer | Manual (involves money, level 30 = eligible) |
| Achievement badges | Maintainer | Manual role assignment when criteria met |
| Streak tracking | GitHub Actions | `bounty-tracker.ts` calculates from PR merge dates |
| Identity linking | contributors.yml | PR-based, reviewed by maintainers |
| Discord notifications | GitHub Actions | Webhook post to `#integrations-announcements` |
## Guides
- **[Setup Guide](bounty-setup-guide.md)** — Complete admin setup from zero to running (30 min)
- **[Game Master Manual](bounty-game-master-manual.md)** — Maintainer operations: posting bounties, reviewing work, managing tiers, anti-gaming
- **[Contributor Guide](bounty-contributor-guide.md)** — Everything a contributor needs to start earning XP and completing bounties
## Reference
- [Integration Promotion Checklist](integration-promotion-checklist.md) — Formal criteria for unverified -> verified
- [Tool README Template](templates/tool-readme-template.md) — Standard format for tool documentation
- [Agent Test Report Template](templates/agent-test-report-template.md) — Standard format for test reports
- [Building Tools Guide](../tools/BUILDING_TOOLS.md) — How to build integrations
- [Parent Issue #2805](https://github.com/adenhq/hive/issues/2805) — Master integration tracking issue
- [Lurkr API Docs](https://lurkr.gg/docs/api) — API reference for XP push
- [Lurkr Leveling Setup](https://lurkr.gg/docs/guides/setting-up-server-leveling) — Bot configuration guide
### Automation Files
- `.github/workflows/bounty-completed.yml` — PR merge → Lurkr XP push + Discord notification
- `.github/workflows/weekly-leaderboard.yml` — Monday leaderboard post
- `scripts/bounty-tracker.ts` — Point calculation, Lurkr API integration, Discord formatting
- `scripts/setup-bounty-labels.sh` — One-time label setup
- `contributors.yml` — GitHub ↔ Discord identity mapping
+99
View File
@@ -0,0 +1,99 @@
# Integration Promotion Checklist
Formal criteria for promoting a tool from **unverified** to **verified**. A tool must satisfy every required item before a maintainer moves it from `_register_unverified()` to `_register_verified()` in [tools/__init__.py](../tools/src/aden_tools/tools/__init__.py).
## Checklist
### Code Quality (Required)
- [ ] **`register_tools` function** follows the standard signature pattern from [BUILDING_TOOLS.md](../tools/BUILDING_TOOLS.md)
- [ ] **Error handling** — all tools return `{"error": ...}` dicts instead of raising exceptions
- [ ] **Credential handling** — graceful fallback when credentials are missing, with actionable `"help"` message
- [ ] **Input validation** — parameters are validated before making API calls
- [ ] **No hardcoded secrets** — API keys come from credentials adapter or environment variables only
### Credential Spec (Required)
- [ ] **CredentialSpec exists** in `tools/src/aden_tools/credentials/{category}.py`
- [ ] **`env_var`** is set and unique (no collisions with other specs)
- [ ] **`tools`** list includes every tool function name registered by this module
- [ ] **`help_url`** points to the page where users get their API key
- [ ] **`description`** is a clear one-liner
- [ ] **`credential_id`** and **`credential_key`** are set for credential store mapping
- [ ] **Spec is merged** into `CREDENTIAL_SPECS` in `credentials/__init__.py`
### Health Check (Required)
- [ ] **`health_check_endpoint`** is set in the CredentialSpec
- [ ] **HealthChecker class** is implemented in `tools/src/aden_tools/credentials/health_check.py`
- [ ] **Checker is registered** in the `HEALTH_CHECKERS` dict
- [ ] **Handles 200** (valid), **401** (invalid/expired), and **429** (rate limited but valid) responses
- [ ] **Registry tests pass**`uv run pytest tools/tests/test_credential_registry.py -v`
### Documentation (Required)
- [ ] **README.md** exists in the tool directory, following the [tool README template](templates/tool-readme-template.md)
- [ ] **Setup instructions** — how to get and configure the API key
- [ ] **Tool table** — lists all tool functions with descriptions
- [ ] **Usage examples** — at least one example per tool function
- [ ] **API reference link** — link to the service's API docs
### Testing (Required)
- [ ] **Unit tests exist** in `tools/tests/tools/test_{tool_name}.py`
- [ ] **Tests mock external APIs** — no live API calls in unit tests
- [ ] **Tests cover happy path** for each tool function
- [ ] **Tests cover error cases** — missing credentials, invalid input, API errors
- [ ] **CI passes**`make check && make test`
### Community Testing (Required)
- [ ] **At least 1 community member** has tested with a real API key
- [ ] **Agent test report submitted** following the [test report template](templates/agent-test-report-template.md)
- [ ] **Tool works in a real agent workflow** (not just isolated function calls)
- [ ] **No blocking issues** reported in the test report
### Optional (Bonus)
- [ ] Multiple community test reports from different testers
- [ ] Rate limit documentation
- [ ] Integration tests with sandboxed API accounts
- [ ] Pagination support for list endpoints
- [ ] Webhook support (if applicable to the service)
## Promotion Process
1. **Contributor opens a PR** that checks off all required items above
2. **PR description** includes links to: the tool README, the health checker, the test report(s)
3. **Maintainer reviews** the checklist — every required item must be verified
4. **Maintainer moves** the tool registration from `_register_unverified()` to `_register_verified()` in `tools/__init__.py`
5. **Maintainer adds the `bounty:promote` label** to the PR — this triggers the GitHub Action to award 50 XP via Lurkr and post a Discord notification
6. **Announcement** auto-posted in `#integrations-announcements` on Discord
## Current Status
### Tools Ready for Promotion Testing
The following 55 unverified tools have implementations, credential specs, and unit tests. They need documentation, health checks, and community testing to be promoted:
<details>
<summary>Full list of unverified tools</summary>
airtable, apify, asana, attio, aws_s3, azure_sql, calendly, cloudinary, confluence,
databricks, docker_hub, duckduckgo, gitlab, google_analytics, google_search_console,
google_sheets, greenhouse, huggingface, jira, kafka, langfuse, linear, lusha,
microsoft_graph, mongodb, n8n, notion, obsidian, pagerduty, pinecone, pipedrive,
plaid, powerbi, pushover, quickbooks, reddit, redis, redshift, salesforce, sap,
shopify, snowflake, supabase, terraform, tines, trello, twilio, twitter, vercel,
yahoo_finance, youtube, youtube_transcript, zendesk, zoho_crm, zoom
</details>
### Gap Summary
| Gap | Count | Bounty Type |
|-----|-------|-------------|
| Missing README | ~41 | `bounty:docs` |
| Missing health_check_endpoint | ~40 | `bounty:health-check` |
| Missing HealthChecker class | ~40 | `bounty:health-check` |
| No community test report | 55 | `bounty:agent-test` |
+90
View File
@@ -0,0 +1,90 @@
# Agent Test Report: {tool_name}
<!-- Submit this report as a comment on the bounty issue, or as a file in a PR. -->
## Summary
- **Tool tested:** `{tool_name}`
- **Tester:** @{github_handle}
- **Date:** {YYYY-MM-DD}
- **Verdict:** Pass / Partial / Fail
## Environment
- **OS:** {e.g., macOS 15.2, Ubuntu 24.04}
- **Python:** {e.g., 3.12.1}
- **Hive version:** {commit hash or version}
- **API tier:** {e.g., Free, Pro — relevant for rate limits}
## Credential Setup
- **Auth method:** {API key / OAuth / Bearer token}
- **Health check result:** {Pass / Fail / No health checker available}
- **Setup difficulty:** {Easy / Medium / Hard}
- **Setup notes:** {Any friction, confusing docs, extra steps not documented}
## Agent Configuration
<!-- Describe the agent you built or used to test this tool. -->
```
Agent name: {name}
Tools used: {tool_name}, {any other tools}
Goal: {What the agent was supposed to accomplish}
```
## Test Results
### Tool Functions Tested
| Function | Input | Expected | Actual | Status |
|----------|-------|----------|--------|--------|
| `{function_name}` | {brief input description} | {expected behavior} | {what happened} | Pass/Fail |
| `{function_name}` | {brief input description} | {expected behavior} | {what happened} | Pass/Fail |
### Agent Workflow Test
<!-- Did the agent successfully use this tool to accomplish a task? -->
**Goal:** {What you asked the agent to do}
**Result:** {What actually happened}
**Session ID:** `{session_id if available}`
### Edge Cases Found
<!-- Document any unexpected behavior, errors, or limitations. -->
| Edge Case | Behavior | Severity |
|-----------|----------|----------|
| {e.g., empty query} | {what happened} | Low/Medium/High |
| {e.g., rate limit hit} | {what happened} | Low/Medium/High |
## Issues Found
<!-- List any bugs or problems. Link to new issues if you filed them. -->
- [ ] {Issue description} — {filed as #XXXX / not yet filed}
- [ ] {Issue description}
## Recommendations
<!-- Suggestions for the tool maintainer. -->
- {e.g., "Error message for missing API key should include the help URL"}
- {e.g., "Rate limit handling should retry with backoff"}
- {e.g., "Ready for promotion after health checker is added"}
## Evidence
<!-- Attach or link to logs, screenshots, or recordings. At minimum, include the session ID or key log output. -->
<details>
<summary>Logs</summary>
```
{Paste relevant log output here}
```
</details>
+71
View File
@@ -0,0 +1,71 @@
# {Tool Name} Tool
<!-- One-liner: what this tool does and what it enables agents to do. -->
{Brief description of what the tool does and its primary use case.}
## Setup
```bash
# Required
export {ENV_VAR}=your-api-key
```
**Get your key:**
1. Go to {help_url}
2. {Step to create/generate a key}
3. {Step to copy the key}
4. Set `{ENV_VAR}` environment variable
Alternatively, configure via the credential store (`CredentialStoreAdapter`).
<!-- If OAuth is supported, add: -->
<!-- **OAuth:** This integration also supports OAuth2 via Aden. -->
## Tools ({count})
| Tool | Description |
|------|-------------|
| `{tool_function_name}` | {What it does} |
| `{tool_function_name}` | {What it does} |
## Usage
### {Action name}
```python
result = {tool_function_name}(
param="value",
)
# Returns: {brief description of return value}
```
### {Action name}
```python
result = {tool_function_name}(
param="value",
)
# Returns: {brief description of return value}
```
## Scope
<!-- What this integration covers in its current form. -->
- {Capability 1}
- {Capability 2}
- {Capability 3}
## Rate Limits
<!-- Document known rate limits if applicable. Remove this section if not relevant. -->
| Tier | Limit |
|------|-------|
| Free | {X requests/minute} |
| Paid | {Y requests/minute} |
## API Reference
- [{Service} API Docs]({url})
+556
View File
@@ -0,0 +1,556 @@
#!/usr/bin/env bun
/**
* Bounty Tracker — calculates points from merged PRs and generates leaderboards.
*
* Modes:
* notify — Post a Discord message for a single completed bounty (called by bounty-completed.yml)
* leaderboard — Generate and post the weekly leaderboard (called by weekly-leaderboard.yml)
*
* Environment:
* GITHUB_TOKEN — GitHub API token
* GITHUB_REPOSITORY_OWNER — e.g. "adenhq"
* GITHUB_REPOSITORY_NAME — e.g. "hive"
* DISCORD_WEBHOOK_URL — Discord webhook for #integrations-announcements
* LURKR_API_KEY — Lurkr Read/Write API key (for XP push)
* LURKR_GUILD_ID — Discord server ID where Lurkr is installed
* PR_NUMBER — (notify mode) The merged PR number
*/
import { readFileSync } from "fs";
import { join } from "path";
// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------
interface Contributor {
github: string;
discord: string;
name?: string;
}
interface GitHubLabel {
name: string;
}
interface GitHubUser {
login: string;
}
interface GitHubPR {
number: number;
title: string;
merged_at: string | null;
labels: GitHubLabel[];
user: GitHubUser;
html_url: string;
}
interface BountyResult {
pr: GitHubPR;
bountyType: string;
points: number;
difficulty: string;
contributor: string;
discordId: string | null;
}
interface LeaderboardEntry {
github: string;
discordId: string | null;
points: number;
bounties: number;
}
// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------
const POINTS: Record<string, number> = {
"bounty:smoke-test": 10,
"bounty:agent-test": 30,
"bounty:docs": 20,
"bounty:health-check": 25,
"bounty:bug-fix": 40,
"bounty:new-tool": 75,
"bounty:promote": 50,
};
// ---------------------------------------------------------------------------
// GitHub API
// ---------------------------------------------------------------------------
async function githubRequest<T>(
endpoint: string,
token: string,
method: string = "GET",
body?: unknown
): Promise<T> {
const headers: Record<string, string> = {
Authorization: `Bearer ${token}`,
Accept: "application/vnd.github.v3+json",
"User-Agent": "bounty-tracker",
};
if (body) {
headers["Content-Type"] = "application/json";
}
const options: RequestInit = { method, headers };
if (body) {
options.body = JSON.stringify(body);
}
const response = await fetch(`https://api.github.com${endpoint}`, options);
if (!response.ok) {
throw new Error(
`GitHub API request failed: ${response.status} ${response.statusText}`
);
}
return response.json();
}
async function getPR(
owner: string,
repo: string,
prNumber: number,
token: string
): Promise<GitHubPR> {
return githubRequest<GitHubPR>(
`/repos/${owner}/${repo}/pulls/${prNumber}`,
token
);
}
async function getMergedBountyPRs(
owner: string,
repo: string,
token: string,
since?: string
): Promise<GitHubPR[]> {
// GitHub search API requires each label with special chars to be quoted individually.
// Multiple label: qualifiers are OR'd together.
const bountyLabels = Object.keys(POINTS)
.map((l) => `label:"${l}"`)
.join(" ");
const query = `repo:${owner}/${repo} is:pr is:merged ${bountyLabels}${since ? ` merged:>=${since}` : ""}`;
const result = await githubRequest<{ items: GitHubPR[] }>(
`/search/issues?q=${encodeURIComponent(query)}&per_page=100&sort=updated&order=desc`,
token
);
return result.items;
}
// ---------------------------------------------------------------------------
// Identity resolution
// ---------------------------------------------------------------------------
// Parse contributors.yml without a YAML dependency.
// The format is simple enough to parse with regex:
// contributors:
// - github: jane-doe
// discord: "123456789012345678"
// name: Jane Doe
function parseContributorsYaml(raw: string): Contributor[] {
const contributors: Contributor[] = [];
let current: Partial<Contributor> | null = null;
for (const line of raw.split("\n")) {
const trimmed = line.trim();
if (trimmed.startsWith("- github:")) {
if (current?.github && current?.discord) {
contributors.push(current as Contributor);
}
current = { github: trimmed.replace("- github:", "").trim() };
} else if (trimmed.startsWith("discord:") && current) {
current.discord = trimmed.replace("discord:", "").trim().replace(/^["']|["']$/g, "");
} else if (trimmed.startsWith("name:") && current) {
current.name = trimmed.replace("name:", "").trim();
}
}
// Don't forget the last entry
if (current?.github && current?.discord) {
contributors.push(current as Contributor);
}
return contributors;
}
function loadContributors(): Map<string, Contributor> {
const map = new Map<string, Contributor>();
try {
// Resolve path relative to the script location (scripts/ dir → repo root)
const scriptDir = new URL(".", import.meta.url).pathname;
const raw = readFileSync(
join(scriptDir, "..", "contributors.yml"),
"utf-8"
);
const entries = parseContributorsYaml(raw);
for (const c of entries) {
map.set(c.github.toLowerCase(), c);
}
} catch {
console.warn("Warning: could not load contributors.yml");
}
return map;
}
function resolveDiscord(
githubUsername: string,
contributors: Map<string, Contributor>
): string | null {
const entry = contributors.get(githubUsername.toLowerCase());
return entry?.discord ?? null;
}
// ---------------------------------------------------------------------------
// Bounty extraction
// ---------------------------------------------------------------------------
function extractBounty(
pr: GitHubPR,
contributors: Map<string, Contributor>
): BountyResult | null {
const labels = pr.labels.map((l) => l.name);
const bountyLabel = labels.find((l) => l.startsWith("bounty:"));
if (!bountyLabel) return null;
const points = POINTS[bountyLabel];
if (points === undefined) return null;
const difficulty =
labels.find((l) => l.startsWith("difficulty:"))?.replace("difficulty:", "") ??
"unknown";
return {
pr,
bountyType: bountyLabel.replace("bounty:", ""),
points,
difficulty,
contributor: pr.user.login,
discordId: resolveDiscord(pr.user.login, contributors),
};
}
// ---------------------------------------------------------------------------
// Discord notifications
// ---------------------------------------------------------------------------
async function postToDiscord(
webhookUrl: string,
content: string,
embeds?: unknown[]
): Promise<void> {
const body: Record<string, unknown> = { content };
if (embeds) body.embeds = embeds;
const response = await fetch(webhookUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
if (!response.ok) {
throw new Error(
`Discord webhook failed: ${response.status} ${response.statusText}`
);
}
}
function formatBountyNotification(bounty: BountyResult): string {
const userMention = bounty.discordId
? `<@${bounty.discordId}>`
: `**${bounty.contributor}**`;
const typeEmoji: Record<string, string> = {
"smoke-test": "\u{1F9EA}",
"agent-test": "\u{1F916}",
docs: "\u{1F4DD}",
"health-check": "\u{1FA7A}",
"bug-fix": "\u{1F41B}",
"new-tool": "\u{1F527}",
promote: "\u{2B50}",
};
const emoji = typeEmoji[bounty.bountyType] ?? "\u{1F3AF}";
let msg = `${emoji} **Bounty Completed!**\n\n`;
msg += `${userMention} completed a **${bounty.bountyType}** bounty (+${bounty.points} pts)\n`;
msg += `PR: ${bounty.pr.html_url}\n`;
if (!bounty.discordId) {
msg += `\n_\u{1F517} @${bounty.contributor}: link your Discord in \`contributors.yml\` to get pinged!_`;
}
return msg;
}
function formatLeaderboard(entries: LeaderboardEntry[]): string {
if (entries.length === 0) {
return "No bounty completions this period.";
}
const sorted = [...entries].sort((a, b) => b.points - a.points);
const top10 = sorted.slice(0, 10);
const medals = ["\u{1F947}", "\u{1F948}", "\u{1F949}"];
let msg = "**\u{1F3C6} Integration Bounty Leaderboard**\n\n";
for (let i = 0; i < top10.length; i++) {
const entry = top10[i];
const rank = medals[i] ?? `**${i + 1}.**`;
const name = entry.discordId
? `<@${entry.discordId}>`
: `**${entry.github}**`;
msg += `${rank} ${name}${entry.points} pts (${entry.bounties} bounties)\n`;
}
msg += `\n_${sorted.length} contributors total_`;
return msg;
}
// ---------------------------------------------------------------------------
// Lurkr API — push XP to Discord leveling system
// ---------------------------------------------------------------------------
const LURKR_BASE_URL = "https://api.lurkr.gg/v2";
interface LurkrLevelResponse {
level: {
level: number;
xp: number;
messageCount: number;
};
}
async function lurkrAddXP(
guildId: string,
userId: string,
xp: number,
apiKey: string
): Promise<LurkrLevelResponse> {
const response = await fetch(
`${LURKR_BASE_URL}/levels/${guildId}/users/${userId}`,
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
"X-API-Key": apiKey,
},
body: JSON.stringify({ xp: { increment: xp } }),
}
);
if (!response.ok) {
const text = await response.text();
throw new Error(`Lurkr API failed: ${response.status} ${text}`);
}
return response.json();
}
async function lurkrGetUser(
guildId: string,
userId: string,
apiKey: string
): Promise<LurkrLevelResponse | null> {
const response = await fetch(
`${LURKR_BASE_URL}/levels/${guildId}/users/${userId}`,
{
method: "GET",
headers: { "X-API-Key": apiKey },
}
);
if (response.status === 404) return null;
if (!response.ok) {
const text = await response.text();
throw new Error(`Lurkr API failed: ${response.status} ${text}`);
}
return response.json();
}
async function awardLurkrXP(bounty: BountyResult): Promise<string | null> {
const apiKey = process.env.LURKR_API_KEY;
const guildId = process.env.LURKR_GUILD_ID;
if (!apiKey || !guildId) {
console.log("Lurkr not configured (missing LURKR_API_KEY or LURKR_GUILD_ID), skipping XP push");
return null;
}
if (!bounty.discordId) {
console.log(`No Discord ID for @${bounty.contributor}, cannot push Lurkr XP`);
return null;
}
try {
const result = await lurkrAddXP(guildId, bounty.discordId, bounty.points, apiKey);
const msg = `Lurkr: +${bounty.points} XP \u2192 <@${bounty.discordId}> (now level ${result.level.level}, ${result.level.xp} XP)`;
console.log(msg);
return msg;
} catch (err) {
// Lurkr failure should not prevent the Discord notification from being sent
console.error(`Lurkr XP push failed (non-fatal): ${err}`);
return null;
}
}
// ---------------------------------------------------------------------------
// Leaderboard calculation
// ---------------------------------------------------------------------------
function buildLeaderboard(
bounties: BountyResult[]
): LeaderboardEntry[] {
const map = new Map<string, LeaderboardEntry>();
for (const b of bounties) {
const key = b.contributor.toLowerCase();
const existing = map.get(key);
if (existing) {
existing.points += b.points;
existing.bounties += 1;
} else {
map.set(key, {
github: b.contributor,
discordId: b.discordId,
points: b.points,
bounties: 1,
});
}
}
return Array.from(map.values());
}
// ---------------------------------------------------------------------------
// CLI
// ---------------------------------------------------------------------------
async function main() {
const mode = process.argv[2];
const token = process.env.GITHUB_TOKEN;
const owner = process.env.GITHUB_REPOSITORY_OWNER;
const repo = process.env.GITHUB_REPOSITORY_NAME;
const webhookUrl = process.env.DISCORD_WEBHOOK_URL;
if (!token || !owner || !repo) {
console.error(
"Missing required env: GITHUB_TOKEN, GITHUB_REPOSITORY_OWNER, GITHUB_REPOSITORY_NAME"
);
process.exit(1);
}
const contributors = loadContributors();
if (mode === "notify") {
// Single bounty notification
const prNumber = parseInt(process.env.PR_NUMBER ?? "", 10);
if (!prNumber) {
console.error("Missing PR_NUMBER env var");
process.exit(1);
}
const pr = await getPR(owner, repo, prNumber, token);
if (!pr.merged_at) {
console.log("PR not merged, skipping");
return;
}
const bounty = extractBounty(pr, contributors);
if (!bounty) {
console.log("No bounty label found, skipping");
return;
}
console.log(
`Bounty: ${bounty.bountyType} | ${bounty.points} pts | @${bounty.contributor}`
);
// Push XP to Lurkr (before Discord notification so we can include level info)
const lurkrMsg = await awardLurkrXP(bounty);
if (webhookUrl) {
let msg = formatBountyNotification(bounty);
if (lurkrMsg) {
msg += `\n${lurkrMsg}`;
}
await postToDiscord(webhookUrl, msg);
console.log("Discord notification sent");
} else {
console.log("No DISCORD_WEBHOOK_URL set, skipping Discord notification");
console.log(formatBountyNotification(bounty));
}
} else if (mode === "leaderboard") {
// Weekly leaderboard
const since = process.env.SINCE_DATE;
const prs = await getMergedBountyPRs(owner, repo, token, since);
console.log(`Found ${prs.length} merged bounty PRs`);
const bounties = prs
.map((pr) => extractBounty(pr, contributors))
.filter((b): b is BountyResult => b !== null);
const entries = buildLeaderboard(bounties);
const msg = formatLeaderboard(entries);
console.log(msg);
if (webhookUrl) {
await postToDiscord(webhookUrl, msg);
console.log("Leaderboard posted to Discord");
}
} else {
console.error("Usage: bounty-tracker.ts <notify|leaderboard>");
console.error(" notify — Post Discord notification for a merged bounty PR");
console.error(" leaderboard — Generate and post the leaderboard");
process.exit(1);
}
}
// Run if invoked directly
main().catch((err) => {
console.error(err);
process.exit(1);
});
// Export for testing
export {
extractBounty,
buildLeaderboard,
formatBountyNotification,
formatLeaderboard,
loadContributors,
resolveDiscord,
awardLurkrXP,
lurkrAddXP,
lurkrGetUser,
POINTS,
};
export type {
BountyResult,
LeaderboardEntry,
Contributor,
GitHubPR,
LurkrLevelResponse,
};
+26
View File
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
# Creates GitHub labels for the Integration Bounty Program.
# Usage: ./scripts/setup-bounty-labels.sh [owner/repo]
# Requires: gh CLI authenticated
set -euo pipefail
REPO="${1:-adenhq/hive}"
echo "Setting up bounty labels for $REPO..."
# Bounty type labels
gh label create "bounty:smoke-test" --repo "$REPO" --color "0E8A16" --description "Bounty: run tool with real API key, report results (10 pts)" --force
gh label create "bounty:agent-test" --repo "$REPO" --color "1D76DB" --description "Bounty: test tool in a real agent workflow (30 pts)" --force
gh label create "bounty:docs" --repo "$REPO" --color "FBCA04" --description "Bounty: write or improve documentation (20 pts)" --force
gh label create "bounty:health-check" --repo "$REPO" --color "D93F0B" --description "Bounty: add health check endpoint or checker (25 pts)" --force
gh label create "bounty:bug-fix" --repo "$REPO" --color "B60205" --description "Bounty: fix a discovered bug (40 pts)" --force
gh label create "bounty:new-tool" --repo "$REPO" --color "6F42C1" --description "Bounty: build a new integration from scratch (75 pts)" --force
gh label create "bounty:promote" --repo "$REPO" --color "C2A000" --description "Bounty: complete full promotion checklist (50 pts)" --force
# Difficulty labels
gh label create "difficulty:easy" --repo "$REPO" --color "BFD4F2" --description "Good first contribution" --force
gh label create "difficulty:medium" --repo "$REPO" --color "D4C5F9" --description "Requires some familiarity" --force
gh label create "difficulty:hard" --repo "$REPO" --color "F9D0C4" --description "Significant effort or expertise needed" --force
echo "Done. Labels created for $REPO."