check / check (pull_request) Successful in 27s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
3.1 KiB
3.1 KiB
name, description
| name | description |
|---|---|
| opencode-v2-plugin | How to write, configure and register an opencode v2 plugin, including adding a websearch provider. Use when writing or editing plugin code, opencode.json `plugins`/`websearch` config, or plugin packaging in this repo. |
opencode v2 plugin
Verified against opencode.ai/v2 docs (build/plugins, plugins, config, websearch). Full evidence and open items: docs/research/opencode-v2-plugin-api.md. The v1 package @opencode-ai/plugin does NOT run in v2.
Entry point
import { Plugin } from "@opencode/plugin"
export default Plugin.define({
id: "home.fastcrw", // required, stable; used for storage scoping and diagnostics
async setup(ctx) {
// ctx.options (plugin options), ctx.storage, ctx.location, ctx.websearch, ...
// may return a cleanup function
},
})
Options are read from ctx.options inside setup, not passed as an argument. They are untyped key/value: validate them yourself.
Websearch provider
await ctx.websearch.transform((editor) => {
editor.add({
id: "fastcrw",
name: "fastCRW (self-hosted)",
execute: async ({ query }, { signal }) => [{ url, title, content, time: {} }],
})
editor.default.set("fastcrw") // make it active; set(false) disables
})
executereturns{ url, title, content, time }[]. Passsignaltofetch.await ctx.websearch.reload()re-evaluates providers.
Config (opencode.json)
{
"plugins": [
{
"package": "@haylan/opencode-fastcrw",
"options": { "baseURL": "http://crw.home:3000", "limit": 8 },
},
],
}
- Key is plural
plugins(v1:plugin). Entries are a string or{ package, options }. packagemay be an npm name (name,name@1.2.0,@scope/name),./relative(resolved from the config file), an absolute path orfile://.~is not expanded.- Local paths must be directories, resolved by file path (
<dir>/server, then<dir>/index);package.jsonexportsare ignored. A file entry is ignored with a warning, and a directory without a rootindex/serverfile loads silently nothing. npm names resolve throughexports. - Auto-discovered:
.ts/.jsfiles (not.mjs) and directories in.opencode/plugins/and~/.config/opencode/plugins/. Drop-in files get no options. websearch.provideris a provider id or"random";"websearch": falsedisables search. Built-in ids: exa, firecrawl, parallel, tavily, tinyfish. A provider named here wins over a plugin'seditor.default.set; with it unset, the plugin's default applies.- CLI:
opencode plugin add|list|check|update|remove(addwrites the global config). - Loading is lazy: after startup or reload the plugin list fills in after several seconds. Load errors show as
state.status: "failed"inGET /api/plugin(private server:opencode serve, Basic auth useropencode).
Packaging (npm)
"type": "module", exports["."] pointing at the entry, dependency on @opencode/plugin.
Still unverified
- Installing by name from the Gitea registry with a scoped
.npmrc.
Verified results: docs/runtime-checks.md.