* feat(health): re-check V1 plugins nightly and guard the sunset removal Listed plugins kept their classified compat forever, so a plugin that migrated after the V1 sunset notice would still be removed on 2027-01-01. The nightly health job now re-detects every plugin not marked v2, opens a bot/health-compat PR for the ones now on V2, removes V1 plugins after the sunset only when the re-check still says V1, and keeps the v1-sunset tracking issue current (one reminder 31 days before the sunset). Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01EHYZtiXaVB71TSBhHnynk4 * fix(health): sanitize logged values flagged by SonarCloud Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01EHYZtiXaVB71TSBhHnynk4 --------- Co-authored-by: John Smith <[email protected]> Co-authored-by: Claude Opus 5.5 <[email protected]>
5.3 KiB
Catalog Policy
How entries get into the catalog, how they are kept honest, and when they leave. Automation enforces most of this; this page is the reference it links to.
Admission
An entry must:
- work with OpenCode;
- point at a public, non-archived repository root (
pathfor a monorepo folder); - be the only entry for that repository and path;
- not be a cryptocurrency, token or trading project (zero tolerance);
- pass
npm run validate(schema, field limits, kind/category fit).
OpenCode V2 requirement for new plugins
New entries in data/plugins/ must use the V2 plugin API: depend on an @opencode/* package (normally @opencode/plugin) and export Plugin.define({ id, setup(ctx) }). Pre-release V2 builds published under the old name (@opencode-ai/[email protected]*, @next, @beta, or @opencode-ai/client) also count. Packages that ship both V1 and V2 entry points count as V2.
The validate check detects this from, in order: the entry's npm package, package.json files in the repository (at path, the root and packages/* / plugins/*), then the source code. Results:
| Detected | New plugin PR | Meaning |
|---|---|---|
v2 |
passes | @opencode/* dependency or Plugin.define found |
v1 |
blocked, labeled needs-v2 |
Only @opencode-ai/plugin/sdk 1.x, or a legacy V1 plugin function without Plugin.define |
unknown |
passes with needs-human |
Nothing conclusive found; a maintainer verifies by hand. Adding npm or path usually resolves it |
PRs labeled needs-v2 are re-checked every night. When the target migrates, the bot relabels the PR, fills in any missing fields on same-repo branches, re-runs validate and tells the author. After 60 days still on V1, the PR is closed; reopen it or resubmit through the issue form after migrating.
Themes, agents, projects and resources are not blocked on V2. Their compat is informational (v2/v1 when they use the SDK, otherwise n/a).
Existing V1 plugins: sunset on 2027-01-01
Plugins already in the catalog that are V1-only carry a V1 only badge in the README and on the site. The nightly health job re-detects every plugin not marked v2; when one is detected as V2 it opens a PR (bot/health-compat) marking the entry compat: v2. After 2027-01-01 V1-only plugins are removed by the health job's removal PR, but only when that night's re-check still detects V1: a V2 or inconclusive result keeps the entry, and inconclusive ones are listed in the health report for a maintainer. Plugins with unknown compatibility are listed there too for manual verification.
The bot keeps the list in the V1 sunset tracking issue (label v1-sunset) current, posts one reminder there 31 days before the sunset, and closes the issue once no V1-only plugins remain.
Health checks and removal
A nightly job checks every entry and maintains the Catalog health report issue.
| Finding | Action |
|---|---|
| Repository renamed or transferred | Bot PR updates the repo URL |
| Repository archived, deleted (404), or npm package deprecated | Listed in the report; removal PR after 30 days if it doesn't recover |
Plugin not marked v2 now detected as V2 |
Bot PR sets compat: v2 |
| V1-only plugin after 2027-01-01, still detected as V1 | Removal PR |
| No push for 6–12 months / 12+ months | quiet / stale badge on the site. Never removed for inactivity alone: small, finished tools are fine |
Removal PRs are reviewed like any other PR; closing one keeps the entries until the next run proposes them again. Git history is the archive; there is no separate retired list.
Discovery
A weekly scout searches npm for packages published since V2 shipped that depend on @opencode/*, keeps public, licensed, non-archived, non-fork repositories that are not already listed or in an open PR, and ranks them by weekly downloads, then stars. It posts a Scout issue; a maintainer ticking a candidate's box makes the bot open a PR for it. Add a package or repo to discovery/declined.txt to stop suggesting it.
Branch protection
main has a ruleset: changes land only through pull requests with a passing validate check (GitHub rulesets do not accept direct pushes while a status check is required), and force-pushes and deletion are blocked. Bots open PRs too; GitHub holds workflow runs on bot-opened PRs for approval, so each bot approves the validate run on its own PR. Repository admins can merge a PR whose check is failing or pending (for a broken CI).
Automation map
| Workflow | When | What |
|---|---|---|
validate-pr.yml |
every PR | Required validate check |
triage.yml |
PR opened/updated | Labels and a results comment (base-branch code only). needs-human is only ever removed by a maintainer |
generate-readme.yml |
push to main | README.md and dist/registry.json; fails without writing on any invalid entry. The regenerated commit goes through a bot PR (bot/readme-*) that merges itself once validate passes |
site.yml |
push to main, daily | Search site on GitHub Pages |
health.yml |
daily | Health report and V1 sunset issues; rename, V2-migration and removal PRs |
reprobe.yml |
daily | Re-checks needs-v2 PRs |
scout.yml |
weekly | Scout issue with V2 plugin candidates |
issues.yml |
issue opened/edited | Issue-form submissions and scout acceptances become PRs |