跳至内容

插件

编写您自己的插件来扩展 OpenCode。

插件允许您通过挂钩到各种事件和自定义行为来扩展 OpenCode。您可以创建插件来添加新功能、与外部服务集成或修改 OpenCode 的默认行为。

有关示例,请查看社区创建的插件


使用插件

有两种加载插件的方式。


从本地文件

将 JavaScript 或 TypeScript 文件放置在插件目录中。

  • .opencode/plugins/ - 项目级插件
  • ~/.config/opencode/plugins/ - 全局插件

这些目录中的文件在启动时会自动加载。


从 npm

在您的配置文件中指定 npm 包。

opencode.json
{
"$schema": "https://opencode.ac.cn/config.json",
"plugin": ["opencode-helicone-session", "opencode-wakatime", "@my-org/custom-plugin"]
}

支持常规和 scoped npm 包。

生态系统中浏览可用插件。


插件如何安装

npm 插件在启动时使用 Bun 自动安装。包及其依赖项缓存于 ~/.cache/opencode/node_modules/

本地插件直接从插件目录加载。要使用外部包,您必须在您的配置目录中创建一个 package.json(参见依赖项),或将插件发布到 npm 并将其添加到您的配置中。


加载顺序

插件从所有来源加载,所有钩子按顺序运行。加载顺序为

  1. 全局配置 (~/.config/opencode/opencode.json)
  2. 项目配置 (opencode.json)
  3. 全局插件目录 (~/.config/opencode/plugins/)
  4. 项目插件目录 (.opencode/plugins/)

同名同版本的重复 npm 包只会加载一次。然而,同名的本地插件和 npm 插件都会被分别加载。


创建插件

插件是一个JavaScript/TypeScript 模块,它导出一个或多个插件函数。每个函数接收一个上下文对象并返回一个钩子对象。


依赖项

本地插件和自定义工具可以使用外部 npm 包。在您的配置目录中添加一个 package.json,其中包含您所需的依赖项。

.opencode/package.json
{
"dependencies": {
"shescape": "^2.1.0"
}
}

OpenCode 在启动时运行 bun install 来安装这些包。您的插件和工具随后可以导入它们。

.opencode/plugins/my-plugin.ts
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)
}
},
}
}

基本结构

.opencode/plugins/example.js
export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
console.log("Plugin initialized!")
return {
// Hook implementations go here
}
}

插件函数接收

  • project: 当前项目信息。
  • directory: 当前工作目录。
  • worktree: Git 工作树路径。
  • client: 用于与 AI 交互的 opencode SDK 客户端。
  • $: Bun 的shell API,用于执行命令。

TypeScript 支持

对于 TypeScript 插件,您可以从插件包中导入类型

my-plugin.ts
import type { Plugin } from "@opencode-ai/plugin"
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
return {
// Type-safe hook implementations
}
}

事件

插件可以订阅事件,如下面的示例部分所示。以下是可用事件的列表。

命令事件

  • command.executed

文件事件

  • file.edited
  • file.watcher.updated

安装事件

  • installation.updated

LSP 事件

  • lsp.client.diagnostics
  • lsp.updated

消息事件

  • message.part.removed
  • message.part.updated
  • message.removed
  • message.updated

权限事件

  • permission.asked
  • permission.replied

服务器事件

  • server.connected

会话事件

  • session.created
  • session.compacted
  • session.deleted
  • session.diff
  • session.error
  • session.idle
  • session.status
  • session.updated

待办事项事件

  • todo.updated

Shell 事件

  • shell.env

工具事件

  • tool.execute.after
  • tool.execute.before

TUI 事件

  • tui.prompt.append
  • tui.command.execute
  • tui.toast.show

示例

以下是一些可用于扩展 opencode 的插件示例。


发送通知

当特定事件发生时发送通知

.opencode/plugins/notification.js
export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => {
return {
event: async ({ event }) => {
// Send notification on session completion
if (event.type === "session.idle") {
await $`osascript -e 'display notification "Session completed!" with title "opencode"'`
}
},
}
}

我们使用 osascript 在 macOS 上运行 AppleScript。这里我们用它来发送通知。


.env 保护

阻止 opencode 读取 .env 文件

.opencode/plugins/env-protection.js
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")
}
},
}
}

注入环境变量

将环境变量注入到所有 shell 执行中(AI 工具和用户终端)

.opencode/plugins/inject-env.js
export const InjectEnvPlugin = async () => {
return {
"shell.env": async (input, output) => {
output.env.MY_API_KEY = "secret"
output.env.PROJECT_ROOT = input.cwd
},
}
}

自定义工具

插件还可以为 opencode 添加自定义工具

.opencode/plugins/custom-tools.ts
import { type Plugin, tool } from "@opencode-ai/plugin"
export const CustomToolsPlugin: Plugin = async (ctx) => {
return {
tool: {
mytool: tool({
description: "This is a custom tool",
args: {
foo: tool.schema.string(),
},
async execute(args, context) {
const { directory, worktree } = context
return `Hello ${args.foo} from ${directory} (worktree: ${worktree})`
},
}),
},
}
}

tool 辅助函数创建一个 opencode 可以调用的自定义工具。它接收一个 Zod 模式函数,并返回一个包含以下内容的工具定义:

  • description: 工具的功能描述
  • args: 工具参数的 Zod 模式
  • execute: 工具被调用时运行的函数

您的自定义工具将与内置工具一起提供给 opencode 使用。


日志记录

使用 client.app.log() 代替 console.log 进行结构化日志记录

.opencode/plugins/my-plugin.ts
export const MyPlugin = async ({ client }) => {
await client.app.log({
body: {
service: "my-plugin",
level: "info",
message: "Plugin initialized",
extra: { foo: "bar" },
},
})
}

级别:debug, info, warn, error。有关详细信息,请参阅SDK 文档


精简钩子

自定义会话精简时包含的上下文

.opencode/plugins/compaction.ts
import type { Plugin } from "@opencode-ai/plugin"
export const CompactionPlugin: Plugin = async (ctx) => {
return {
"experimental.session.compacting": async (input, output) => {
// Inject additional context into the compaction prompt
output.context.push(`
## Custom Context
Include any state that should persist across compaction:
- Current task status
- Important decisions made
- Files being actively worked on
`)
},
}
}

experimental.session.compacting 钩子在 LLM 生成续篇摘要之前触发。使用它来注入默认精简提示可能遗漏的领域特定上下文。

您还可以通过设置 output.prompt 来完全替换精简提示。

.opencode/plugins/custom-compaction.ts
import type { Plugin } from "@opencode-ai/plugin"
export const CustomCompactionPlugin: Plugin = async (ctx) => {
return {
"experimental.session.compacting": async (input, output) => {
// Replace the entire compaction prompt
output.prompt = `
You are generating a continuation prompt for a multi-agent swarm session.
Summarize:
1. The current task and its status
2. Which files are being modified and by whom
3. Any blockers or dependencies between agents
4. The next steps to complete the work
Format as a structured prompt that a new agent can use to resume work.
`
},
}
}

当设置了 output.prompt 时,它将完全替换默认的精简提示。output.context 数组在这种情况下将被忽略。