Files
oc/skills/opencode-plugins/templates/rpc-effect.ts
T
xiaoshuai 15a1bbcee0 Version OpenCode skills and plugins
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
2026-10-08 13:12:10 +08:00

56 lines
2.2 KiB
TypeScript

// RPC contract (Effect flavor) — template
//
// Docs: https://opencode.ai/v2/docs/build/plugins/effect/rpc/
//
// Copy to src/rpc.ts — the implementation template's doc-accurate import is
// "./rpc.js", so the file must be named rpc.ts. Contract only, no
// implementation. Same contract shape as rpc.ts, but with Effect Schema
// instead of raw JSON Schema. Registered by rpc-implementation-effect.ts.
//
// Rpc.define is imported from "@opencode/plugin/rpc" here too, NOT from
// "@opencode/plugin/effect". The Effect page imports Schema from the root
// "effect" module.
//
// TYPE NOTE: the shipped `ValueSchema` type is
// Schema.Codec | StandardSchemaV1 | JsonSchema
// and Effect's `Schema.Struct` is not a `Codec`, so `tsc --strict` can reject
// the form below. The page states JSON Schema and Standard Schema are supported
// here too, so either of these typechecks instead:
// input: { type: "object", properties: { query: { type: "string" } }, required: ["query"] }
// input: z.object({ query: z.string() }) // or Valibot / ArkType
// A method needs BOTH input and output to be present for the types to line up.
//
// 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"
import { Schema } from "effect"
export const Acme = Rpc.define({
// The page does not describe how `id` affects method routing. Pick a name
// that will not collide.
id: "acme",
methods: {
search: {
// Effect Schema validates and infers types, so the handler needs no casts.
input: Schema.Struct({ query: Schema.String }),
output: Schema.Struct({ text: Schema.String }),
// Omit input or output if the method takes or returns nothing.
// Each error key becomes the error's `type`.
errors: {
not_found: Schema.Struct({ query: Schema.String }),
},
},
},
events: {
// Event data must be an object.
updated: {
schema: Schema.Struct({ itemID: Schema.String, text: Schema.String }),
},
},
})
// The Effect page also states that JSON Schema and Standard Schema are
// supported here, so an Effect contract is not restricted to Effect Schema.