Plugins
OpenCode を拡張する独自のプラグインを書きます。
プラグインを使うと、さまざまなイベントにフックして動作をカスタマイズすることで、OpenCode を拡張できます。プラグインを作成して、新機能の追加、外部サービスとの連携、OpenCode のデフォルト動作の変更ができます。
例については、コミュニティが作成したプラグインをご覧ください。
Use a plugin
プラグインを読み込む方法は 2 つあります。
From local files
JavaScript または TypeScript ファイルをプラグインディレクトリに配置します。
.opencode/plugins/- プロジェクトレベルのプラグイン~/.config/opencode/plugins/- グローバルプラグイン
これらのディレクトリ内のファイルは、起動時に自動的に読み込まれます。
From npm
設定ファイルで npm パッケージを指定します。
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-helicone-session", "opencode-wakatime", "@my-org/custom-plugin"]
}通常の npm パッケージとスコープ付き npm パッケージの両方がサポートされています。
利用可能なプラグインはエコシステムで閲覧できます。
How plugins are installed
npm プラグインは、起動時に Bun を使って自動的にインストールされます。パッケージとその依存関係は ~/.cache/opencode/node_modules/ にキャッシュされます。
ローカルプラグインは、プラグインディレクトリから直接読み込まれます。外部パッケージを使うには、設定ディレクトリ内に package.json を作成する(Dependencies を参照)か、プラグインを npm に公開して設定に追加する必要があります。
Load order
プラグインはすべてのソースから読み込まれ、すべてのフックが順番に実行されます。読み込み順は次のとおりです:
- グローバル設定(
~/.config/opencode/opencode.json) - プロジェクト設定(
opencode.json) - グローバルプラグインディレクトリ(
~/.config/opencode/plugins/) - プロジェクトプラグインディレクトリ(
.opencode/plugins/)
同じ名前とバージョンの重複した npm パッケージは一度だけ読み込まれます。ただし、似た名前のローカルプラグインと npm プラグインは、両方とも別々に読み込まれます。
Create a plugin
プラグインは、1 つ以上のプラグイン関数をエクスポートする JavaScript/TypeScript モジュールです。各関数はコンテキストオブジェクトを受け取り、フックオブジェクトを返します。
Dependencies
ローカルプラグインとカスタムツールは、外部の 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)
}
},
}
}Basic structure
export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
console.log("Plugin initialized!")
return {
// Hook implementations go here
}
}プラグイン関数は次のものを受け取ります:
project: 現在のプロジェクト情報。directory: 現在の作業ディレクトリ。worktree: git worktree のパス。client: AI とやり取りするための opencode SDK クライアント。$: コマンドを実行するための Bun のシェル API (opens in a new tab)。
TypeScript support
TypeScript プラグインでは、プラグインパッケージから型をインポートできます:
import type { Plugin } from "@opencode-ai/plugin"
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
return {
// Type-safe hook implementations
}
}Events
プラグインは、下記の Examples セクションで示すようにイベントを購読できます。以下は利用可能なさまざまなイベントの一覧です。
Command Events
command.executed
File Events
file.editedfile.watcher.updated
Installation Events
installation.updated
LSP Events
lsp.client.diagnosticslsp.updated
Message Events
message.part.removedmessage.part.updatedmessage.removedmessage.updated
Permission Events
permission.askedpermission.replied
Server Events
server.connected
Session Events
session.createdsession.compactedsession.deletedsession.diffsession.errorsession.idlesession.statussession.updated
Todo Events
todo.updated
Shell Events
shell.env
Tool Events
tool.execute.aftertool.execute.before
TUI Events
tui.prompt.appendtui.command.executetui.toast.show
Examples
ここでは、opencode を拡張するために使えるプラグインの例をいくつか紹介します。
Send notifications
特定のイベントが発生したときに通知を送信します:
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"'`
}
},
}
}ここでは macOS で AppleScript を実行するために osascript を使用しています。この例では、通知を送信するために使っています。
注記: OpenCode デスクトップアプリを使っている場合、レスポンスの準備ができたときやセッションがエラーになったときに、システム通知を自動的に送信できます。
.env protection
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")
}
},
}
}Inject environment variables
すべてのシェル実行(AI ツールとユーザーのターミナル)に環境変数を挿入します:
export const InjectEnvPlugin = async () => {
return {
"shell.env": async (input, output) => {
output.env.MY_API_KEY = "secret"
output.env.PROJECT_ROOT = input.cwd
},
}
}Custom tools
プラグインは opencode にカスタムツールを追加することもできます:
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 で利用できるようになります。
注記: プラグインのツールが組み込みツールと同じ名前を使う場合、プラグインのツールが優先されます。
Logging
構造化ログには、console.log の代わりに client.app.log() を使用します:
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 ドキュメント (opens in a new tab)を参照してください。
Compaction hooks
セッションが圧縮されるときに含まれるコンテキストをカスタマイズします:
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 を設定することで、圧縮プロンプトを完全に置き換えることもできます:
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 配列は無視されます。