プラグイン
独自のプラグインを作成して OpenCode を拡張できます。
プラグインを使用すると、さまざまなイベントにフックして動作をカスタマイズすることで OpenCode を拡張できます。新機能の追加、外部サービスとの統合、OpenCode のデフォルト動作の変更などのプラグインを作成できます。
コミュニティが作成したプラグインの例をご覧ください。
プラグインを使用する
プラグインを読み込む方法は2つあります。
ローカルファイルから
JavaScript または TypeScript ファイルをプラグインディレクトリに配置します。
.opencode/plugins/- プロジェクトレベルのプラグイン~/.config/opencode/plugins/- グローバルプラグイン
これらのディレクトリ内のファイルは起動時に自動的に読み込まれます。
npm から
設定ファイルで npm パッケージを指定します。
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-helicone-session", "opencode-wakatime", "@my-org/custom-plugin"]
}通常の npm パッケージとスコープ付き npm パッケージの両方がサポートされています。
エコシステムで利用可能なプラグインを参照してください。
プラグインのインストール方法
npm プラグインは起動時に Bun を使用して自動的にインストールされます。パッケージとその依存関係は ~/.cache/opencode/node_modules/ にキャッシュされます。
ローカルプラグインはプラグインディレクトリから直接読み込まれます。外部パッケージを使用するには、設定ディレクトリ内に package.json を作成する(依存関係を参照)か、プラグインを npm に公開して設定に追加する必要があります。
読み込み順序
プラグインはすべてのソースから読み込まれ、すべてのフックが順番に実行されます。読み込み順序は以下の通りです:
- グローバル設定 (
~/.config/opencode/opencode.json) - プロジェクト設定 (
opencode.json) - グローバルプラグインディレクトリ (
~/.config/opencode/plugins/) - プロジェクトプラグインディレクトリ (
.opencode/plugins/)
同じ名前とバージョンの重複する npm パッケージは一度だけ読み込まれます。ただし、類似した名前のローカルプラグインと npm プラグインは別々に読み込まれます。
プラグインを作成する
プラグインは、1つ以上のプラグイン関数をエクスポートする 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("Plugin initialized!")
return {
// フックの実装をここに記述
}
}プラグイン関数は以下を受け取ります:
project:現在のプロジェクト情報。directory:現在の作業ディレクトリ。worktree:git worktree パス。client:AI と対話するための opencode SDK クライアント。$:コマンドを実行するための Bun の shell API (opens in a new tab)。
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.askedpermission.replied
サーバーイベント
server.connected
セッションイベント
session.createdsession.compactedsession.deletedsession.diffsession.errorsession.idlesession.statussession.updated
Todo イベント
todo.updated
Shell イベント
shell.env
ツールイベント
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"'`
}
},
}
}macOS で AppleScript を実行するために osascript を使用しています。ここでは通知を送信するために使用しています。
注意: OpenCode デスクトップアプリを使用している場合、レスポンスの準備ができたときやセッションでエラーが発生したときに自動的にシステム通知を送信できます。
.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")
}
},
}
}環境変数を注入する
すべての shell 実行(AI ツールとユーザーターミナル)に環境変数を注入します:
export const InjectEnvPlugin = async () => {
return {
"shell.env": async (input, output) => {
output.env.MY_API_KEY = "secret"
output.env.PROJECT_ROOT = input.cwd
},
}
}カスタムツール
プラグインは 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 で利用可能になります。
ロギング
構造化ロギングには 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)を参照してください。
コンパクションフック
セッションがコンパクトされるときに含まれるコンテキストをカスタマイズします:
import type { Plugin } from "@opencode-ai/plugin"
export const CompactionPlugin: Plugin = async (ctx) => {
return {
"experimental.session.compacting": async (input, output) => {
// コンパクションプロンプトに追加のコンテキストを注入
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) => {
// コンパクションプロンプト全体を置き換え
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 配列は無視されます。