File size: 2,845 Bytes
0dbc9de | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | # OpenCode V2 Effect Plugin API
The Effect plugin API grants plugins two in-process capabilities:
- `hook` installs behavior at an OpenCode extension point.
- `reload` reruns every transform hook for a stateful domain.
The public server client will be exposed separately. It is intentionally not part of `PluginContext` yet.
## Defining A Plugin
```ts
import { define } from "@opencode-ai/plugin/v2/effect"
import { Effect } from "effect"
export const Plugin = define({
id: "example",
effect: Effect.fn(function* (ctx) {
yield* ctx.catalog.transform((catalog) => {
catalog.provider.update("example", (provider) => {
provider.name = "Example"
})
})
}),
})
```
Plugin setup registers hooks imperatively. It does not return a hook object.
Configuration supplied for the plugin is available as `ctx.options`.
Registrations are owned by the plugin scope. Closing the scope removes them automatically; a registration may also be removed early through `dispose`.
## Transform Hooks
Transform hooks contribute to stateful domains:
```ts
yield *
ctx.agent.transform((agent) => {
agent.update("reviewer", (item) => {
item.description = "Reviews code for regressions"
item.mode = "subagent"
})
})
```
OpenCode rebuilds the domain when a transform is registered or disposed. A rebuild starts from fresh domain state and runs every active transform in registration order.
Available transform hooks are namespaced by domain:
```ts
ctx.agent.transform
ctx.catalog.transform
ctx.command.transform
ctx.integration.transform
ctx.reference.transform
ctx.skill.transform
```
## Runtime Hooks
Runtime hooks intercept live operations rather than rebuilding domain state:
```ts
yield *
ctx.aisdk.sdk(
Effect.fn(function* (event) {
if (event.package !== "@ai-sdk/xai") return
const mod = yield* Effect.promise(() => import("@ai-sdk/xai"))
event.sdk = mod.createXai(event.options)
}),
)
yield *
ctx.aisdk.language((event) => {
if (event.model.providerID !== "xai") return
event.language = event.sdk.responses(event.model.api.id)
})
```
Hooks run sequentially in registration order. Later hooks observe mutations made by earlier hooks.
## Reloading A Domain
When data captured by a transform changes, reload the affected domain:
```ts
let data = yield * loadCatalog()
yield *
ctx.catalog.transform((catalog) => {
applyCatalog(data, catalog)
})
data = yield * loadCatalog()
yield * ctx.catalog.reload()
```
Reload belongs to the domain, not an individual registration. `ctx.catalog.reload()` reruns every active catalog transform and publishes the rebuilt catalog.
Available reload operations are:
```ts
ctx.agent.reload()
ctx.catalog.reload()
ctx.command.reload()
ctx.integration.reload()
ctx.reference.reload()
ctx.skill.reload()
```
|