プラグイン
プラグインを使用すると、さまざまなイベントにフックして動作をカスタマイズすることで、OpenCode を拡張できます。新しい機能を追加したり、外部サービスと統合したり、OpenCode のデフォルトの動作を変更するためのプラグインを作成できます。
例として、コミュニティが作成した plugins を確認してください。
プラグインの使用
プラグインを読み込むには 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 パッケージの両方がサポートされています。
利用可能なプラグインは ecosystem で確認できます。
プラグインのインストール方法
npm プラグイン は、起動時に Bun を使用して自動的にインストールされます。パッケージとその依存関係は ~/.cache/opencode/node_modules/ にキャッシュされます。
ローカルプラグイン は、プラグインディレクトリから直接読み込まれます。外部パッケージを使用するには、設定ディレクトリ内に package.json を作成する必要があります (依存関係 を参照)、またはプラグインを npm に公開して 設定に追加 してください。
読み込み順序
プラグインはすべてのソースから読み込まれ、すべてのフックが順番に実行されます。読み込み順序は次のとおりです。
- グローバル設定 (
~/.config/opencode/opencode.json) - プロジェクト設定 (
opencode.json) - グローバルプラグインディレクトリ (
~/.config/opencode/plugins/) - プロジェクトプラグインディレクトリ (
.opencode/plugins/)
同じ名前とバージョンの重複する npm パッケージは一度だけ読み込まれます。ただし、類似した名前のローカルプラグインと npm プラグインは別々に読み込まれます。
プラグインの作成
プラグインは JavaScript/TypeScript モジュール であり、1 つ以上のプラグイン関数をエクスポートします。各関数はコンテキストオブジェクトを受け取り、フックオブジェクトを返します。
依存関係
ローカルプラグインとカスタムツールは外部の 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。
TypeScript サポート
TypeScript プラグインの場合、プラグインパッケージから型をインポートできます。
import type { Plugin } from "@opencode-ai/plugin"
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
return {
// 型安全なフック実装
}
}
イベント
プラグインは Examples セクションの例のようにイベントをサブスクライブできます。利用可能なさまざまなイベントの一覧を次に示します。
コマンドイベント
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.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 を使用しています。通知を送信するために使用しています。
.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")
}
},
}
}
環境変数の注入
すべてのシェル実行 (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 ドキュメント を参照してください。
圧縮フック
セッションが圧縮されるときに含まれるコンテキストをカスタマイズします。
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 = `
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 配列は無視されます。