15a1bbcee0
Repository sits at the OpenCode config root rather than inside skills/ or
plugins/. OpenCode scans exactly those two subdirectories, and a .git
directory inside either one is picked up as a plugin and fails to load:
loading plugin id=.../plugins/.git entrypoint=.../plugins/.git/index
failed to load plugin ... AggregateError: 2 errors building .../plugins/.git/index
The watcher.ignore config option does not help: it only suppresses filesystem
update events, not plugin discovery, and the "-" disable prefix only applies to
plugins listed in opencode.json(c), not auto-discovered ones.
.gitignore admits only skills/ and plugins/ (plus itself). Personal config
(opencode.jsonc, cli.json, service.json) and node_modules stay local.
skills/opencode-plugins V2-only plugin authoring reference and 7 templates,
transcribed from the V2 docs with the URL on every file
plugins/searxng-search searxng_search tool over a self-hosted SearXNG JSON API
70 lines
2.4 KiB
TypeScript
70 lines
2.4 KiB
TypeScript
// RPC contract — template
|
|
//
|
|
// Docs: https://opencode.ai/v2/docs/build/plugins/rpc/
|
|
//
|
|
// Copy to src/rpc.ts. This file is the contract only — no implementation.
|
|
// Registered by rpc-implementation.ts (Promise) or rpc-implementation-effect.ts
|
|
// (Effect). Use rpc-effect.ts instead if you want Effect Schema.
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// PREREQUISITE: install @opencode/plugin at your OpenCode version and restart
|
|
// the service — see the PREREQUISITE block in promise-plugin.ts.
|
|
// ---------------------------------------------------------------------------
|
|
import { Rpc } from "@opencode/plugin/rpc"
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// src/rpc.ts — the contract. No implementation here.
|
|
//
|
|
// Schemas may be JSON Schema (simple, no deps; values are `unknown` in
|
|
// TypeScript so narrow them) or any Standard Schema validator such as Zod,
|
|
// Valibot, or ArkType (types are inferred).
|
|
//
|
|
// Error names starting with "rpc." are reserved by OpenCode.
|
|
// Event data must be an object: scalars, arrays, null, and undefined are invalid.
|
|
export const Acme = Rpc.define({
|
|
// The page shows received event types arriving prefixed, e.g. rpc.acme.updated.
|
|
// It does not otherwise describe how `id` affects method routing.
|
|
id: "acme",
|
|
methods: {
|
|
search: {
|
|
input: {
|
|
type: "object",
|
|
properties: { query: { type: "string" } },
|
|
required: ["query"],
|
|
additionalProperties: false,
|
|
},
|
|
output: {
|
|
type: "object",
|
|
properties: { text: { type: "string" } },
|
|
required: ["text"],
|
|
additionalProperties: false,
|
|
},
|
|
// Omit input or output entirely if the method takes or returns nothing.
|
|
errors: {
|
|
// Each key becomes the error's `type`; this schema defines its `data`.
|
|
not_found: {
|
|
type: "object",
|
|
properties: { query: { type: "string" } },
|
|
required: ["query"],
|
|
additionalProperties: false,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
events: {
|
|
updated: {
|
|
schema: {
|
|
type: "object",
|
|
properties: {
|
|
itemID: { type: "string" },
|
|
text: { type: "string" },
|
|
},
|
|
required: ["itemID", "text"],
|
|
additionalProperties: false,
|
|
},
|
|
},
|
|
// No data at all? Use an empty object schema.
|
|
// refreshed: { schema: { type: "object", additionalProperties: false } },
|
|
},
|
|
})
|