日本語
ドキュメント
プラグイン

プラグイン

OpenCode を拡張する独自のプラグインを書きます。

プラグインを使うと、さまざまなイベントにフックして動作をカスタマイズすることで、OpenCode を拡張できます。プラグインを作成して、新機能の追加、外部サービスとの連携、OpenCode のデフォルト動作の変更ができます。

例については、コミュニティが作成したプラグインをご覧ください。


プラグインの使用

プラグインを読み込む方法は 2 つあります。


ローカルファイルから

JavaScript または TypeScript ファイルをプラグインディレクトリに配置します。

  • .opencode/plugins/ - プロジェクトレベルのプラグイン
  • ~/.config/opencode/plugins/ - グローバルプラグイン

これらのディレクトリ内のファイルは、起動時に自動的に読み込まれます。


npm から

設定ファイルで npm パッケージを指定します。

opencode.json
{
  "$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 を作成する(Dependencies を参照)か、プラグインを npm に公開して設定に追加する必要があります。


読み込み順序

プラグインはすべてのソースから読み込まれ、すべてのフックが順番に実行されます。読み込み順は次のとおりです:

  1. グローバル設定( ~/.config/opencode/opencode.json )
  2. プロジェクト設定( opencode.json )
  3. グローバルプラグインディレクトリ( ~/.config/opencode/plugins/ )
  4. プロジェクトプラグインディレクトリ( .opencode/plugins/ )

同じ名前とバージョンの重複した npm パッケージは一度だけ読み込まれます。ただし、似た名前のローカルプラグインと npm プラグインは、両方とも別々に読み込まれます。


プラグインの作成

プラグインは、1 つ以上のプラグイン関数をエクスポートする 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 worktree のパス。
  • client : AI とやり取りするための opencode SDK クライアント。
  • $ : コマンドを実行するための Bun のシェル API (opens in a new tab)。

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
  }
}

イベント

プラグインは、下記の Examples セクションで示すようにイベントを購読できます。以下は利用可能なさまざまなイベントの一覧です。

コマンドイベント

  • 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.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"'`
      }
    },
  }
}

ここでは macOS で AppleScript を実行するために osascript を使用しています。この例では、通知を送信するために使っています。

注記: OpenCode デスクトップアプリを使っている場合、レスポンスの準備ができたときやセッションがエラーになったときに、システム通知を自動的に送信できます。


.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")
      }
    },
  }
}

環境変数の注入

すべてのシェル実行(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 で利用できるようになります。

注記: プラグインのツールが組み込みツールと同じ名前を使う場合、プラグインのツールが優先されます。


ログ記録

構造化ログには、console.log の代わりに client.app.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 配列は無視されます。

文書の出典(MIT)