插件
编写你自己的插件来扩展 OpenCode。
插件允许您通过钩入各种事件和自定义行为来扩展 OpenCode。您可以创建插件来添加新功能、与外部服务集成或修改 OpenCode 的默认行为。
有关示例,请查看社区创建的插件。
使用插件
有两种加载插件的方式。
从本地文件加载
将 JavaScript 或 TypeScript 文件放置在插件目录中。
.opencode/plugin/- 项目级插件~/.config/opencode/plugin/- 全局插件
这些目录中的文件会在启动时自动加载。
从 npm 加载
在您的配置文件中指定 npm 包。
{ "$schema": "https://opencode.ai/config.json", "plugin": ["opencode-helicone-session", "opencode-wakatime", "@my-org/custom-plugin"]}支持常规 npm 包和作用域包。
在生态系统中浏览可用的插件。
插件如何安装
npm 插件会在启动时使用 Bun 自动安装。包及其依赖项会被缓存到 ~/.cache/opencode/node_modules/ 目录中。
本地插件直接从插件目录加载。要使用外部包,您必须在配置目录内创建一个 package.json 文件(请参阅依赖项),或者将插件发布到 npm 并将其添加到您的配置中。
加载顺序
插件会从所有来源加载,并且所有钩子按顺序运行。加载顺序如下:
- 全局配置 (
~/.config/opencode/opencode.json) - 项目配置 (
opencode.json) - 全局插件目录 (
~/.config/opencode/plugin/) - 项目插件目录 (
.opencode/plugin/)
具有相同名称和版本的重复 npm 包只加载一次。但是,具有相似名称的本地插件和 npm 插件会分别加载。
创建插件
插件是一个 JavaScript/TypeScript 模块,它导出一个或多个插件函数。每个函数接收一个上下文对象并返回一个钩子对象。
依赖项
本地插件和自定义工具可以使用外部 npm 包。在你的配置目录中添加一个 package.json 文件,包含你需要的依赖项。
{ "dependencies": { "shescape": "^2.1.0" }}OpenCode 在启动时会运行 bun install 来安装这些依赖项。然后你的插件和工具就可以导入它们。
import { escape } from "shescape"
export const MyPlugin = async (ctx) => { return { "tool.execute.before": async (input, output) => { if (input.tool === "bash") { output.args.command = escape(output.args.command) } }, }}基本结构
export const MyPlugin = async ({ project, client, $, directory, worktree }) => { console.log("插件已初始化!")
return { // 钩子实现放在这里 }}插件函数接收:
project:当前项目信息。directory:当前工作目录。worktree:git 工作树路径。client:一个用于与 AI 交互的 opencode SDK 客户端。$:用于执行命令的 Bun shell API。
TypeScript 支持
对于 TypeScript 插件,你可以从插件包导入类型:
import type { Plugin } from "@opencode-ai/plugin"
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => { return { // 类型安全的钩子实现 }}事件
插件可以订阅事件,如下面的示例部分所示。以下是可用的事件列表。
命令事件
command.executed
文件事件
file.editedfile.watcher.updated
安装事件
installation.updated
LSP 事件
lsp.client.diagnosticslsp.updated
消息事件
message.part.removedmessage.part.updatedmessage.removedmessage.updated
权限事件
permission.repliedpermission.updated
服务器事件
server.connected
会话事件
session.createdsession.compactedsession.deletedsession.diffsession.errorsession.idlesession.statussession.updated
待办事项事件
todo.updated
工具事件
tool.execute.aftertool.execute.before
TUI 事件
tui.prompt.appendtui.command.executetui.toast.show
示例
以下是一些可以用来扩展 opencode 的插件示例。
发送通知
在特定事件发生时发送通知:
export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => { return { event: async ({ event }) => { // 会话完成时发送通知 if (event.type === "session.idle") { await $`osascript -e 'display notification "Session completed!" with title "opencode"'` } }, }}我们使用 osascript 在 macOS 上运行 AppleScript。这里我们用它来发送通知。
.env 文件保护
防止 opencode 读取 .env 文件:
export const EnvProtection = async ({ project, client, $, directory, worktree }) => { return { "tool.execute.before": async (input, output) => { if (input.tool === "read" && output.args.filePath.includes(".env")) { throw new Error("Do not read .env files") } }, }}自定义工具
插件也可以向 opencode 添加自定义工具:
import { type Plugin, tool } from "@opencode-ai/plugin"
export const CustomToolsPlugin: Plugin = async (ctx) => { return { tool: { mytool: tool({ description: "这是一个自定义工具", args: { foo: tool.schema.string(), }, async execute(args, ctx) { return `Hello ${args.foo}!` }, }), }, }}tool 辅助函数创建一个 opencode 可以调用的自定义工具。它接收一个 Zod 模式函数并返回一个工具定义,包含:
description:工具的功能描述args:工具参数的 Zod 模式execute:工具被调用时执行的函数
你的自定义工具将与内置工具一起对 opencode 可用。
日志记录
使用 client.app.log() 代替 console.log 进行结构化日志记录:
export const MyPlugin = async ({ client }) => { await client.app.log({ service: "my-plugin", level: "info", message: "插件已初始化", extra: { foo: "bar" }, })}日志级别:debug、info、warn、error。详情请参阅 SDK 文档。
压缩钩子
自定义会话被压缩时包含的上下文:
import type { Plugin } from "@opencode-ai/plugin"
export const CompactionPlugin: Plugin = async (ctx) => { return { "experimental.session.compacting": async (input, output) => { // 向压缩提示词中注入额外的上下文 output.context.push(`
## 自定义上下文
包含应在压缩过程中持久化的任何状态:- 当前任务状态- 已做出的重要决策- 正在积极处理的文件`) }, }}experimental.session.compacting 钩子在 LLM 生成延续摘要之前触发。使用它可以注入默认压缩提示词可能遗漏的领域特定上下文。
您也可以通过设置 output.prompt 来完全替换压缩提示词:
import type { Plugin } from "@opencode-ai/plugin"
export const CustomCompactionPlugin: Plugin = async (ctx) => { return { "experimental.session.compacting": async (input, output) => { // 替换整个压缩提示词 output.prompt = `您正在为多智能体集群会话生成一个延续提示词。
请总结:1. 当前任务及其状态2. 哪些文件正在被修改以及由谁修改3. 任何阻塞或智能体之间的依赖关系4. 完成工作的后续步骤
格式化为新智能体可以用来恢复工作的结构化提示词。` }, }}当设置了 output.prompt 时,它将完全替换默认的压缩提示词。在这种情况下,output.context 数组将被忽略。