OpenCodeの設定 - プラグイン
概要
OpenCodeのプラグインシステムは、TypeScript / JavaScriptで記述したソースコードをOpenCodeの動作に組み込み、独自の機能拡張を実現する仕組みである。
プラグインはフック (hook) ベースのイベント駆動型アーキテクチャを採用しており、
セッションの開始・終了、ファイル操作、ツール実行、シェルコマンドの実行といった各種イベントに対して処理を追加できる。
プラグインが提供する主な機能は以下の通りである。
- セッション管理の拡張
- セッションの作成・削除・アイドル状態等のイベントに反応して処理を追加する。
- ツール実行の制御
- ツール実行前後に検証・変換・ログ記録等の処理を挿入する。
- 環境変数の注入
- シェル実行時にプロジェクト固有の環境変数を動的に追加する。
- カスタムツールの定義
- LLMが呼び出せる独自のツールを作成し、OpenCodeの機能を拡張する。
プラグインはプロジェクト固有 または グローバルに配置でき、OpenCode起動時に自動的に読み込まれる。
プラグインの基本構造
プラグインは非同期関数として実装されており、コンテキストオブジェクトを引数として受け取り、フックオブジェクトを返す構造を持つ。
基本的なプラグインの構造を以下に示す。
import { Plugin } from "opencode/plugin"
export const MyPlugin: Plugin = async ({ client, project, $, directory }) => {
// 初期化処理をここに記述する
return {
"session.created": async ({ session }) => {
// セッション作成時の処理
},
"tool.execute.before": async ({ tool, args }) => {
// ツール実行前の処理
}
}
}
コンテキストはデストラクチャリングで受け取ることが重要である。
- 正しい記述方法
async ({ client, project, $ }) => { ... }
- 誤った記述方法
async (client, project, $) => { ... }
コンテキストオブジェクト
コンテキストオブジェクトには、プラグイン内で利用できる各種情報とAPIが含まれる。
| プロパティ | 説明 |
|---|---|
client |
OpenCode SDKクライアント ログ出力やAPI呼び出しに使用する。 例: client.app.log("info", "メッセージ")
|
project |
プロジェクト情報 現在のプロジェクトのメタデータにアクセスできる。 |
$ |
シェルコマンド実行用のAPI (BunのShell API) プラグイン内からシェルコマンドを実行する時に使用する。 |
directory |
現在の作業ディレクトリのパス |
worktree |
ワークツリー情報 Gitのワークツリーに関する情報にアクセスできる。 |
app |
アプリケーション参照 OpenCodeアプリケーション全体への参照を提供する。 |
フックオブジェクト
フックオブジェクトは、プラグインが対応する各イベントとその処理関数をマッピングしたオブジェクトである。
フックオブジェクトの基本的な構造を以下に示す。
return {
// イベント名: 処理関数
"session.created": async ({ session }) => { ... },
"tool.execute.before": async ({ tool, args }) => { ... },
"shell.env": async ({ env }) => { ... }
}
フックの処理関数は非同期関数として定義して、イベントに応じたパラメータを受け取る。
一部のフックでは、受け取ったパラメータを変更して返すことにより、OpenCodeの動作を変更できる。
ディレクトリ構造
プラグインは以下の2つの場所に配置できる。
- プロジェクト固有のプラグイン
- .opencode/plugins/
- 特定のプロジェクトにのみ適用される。
- グローバルプラグイン
- ~/.config/opencode/plugins/
- 全てのプロジェクトで使用できる。
OpenCode起動時に上記のディレクトリが自動的にスキャンされ、プラグインが読み込まれる。
npmパッケージとして配布されているプラグインは、opencode.jsonファイル の plugins フィールドに指定することで使用できる。
{
"plugins": [
"opencode-plugin-example",
"./local-plugin"
]
}
プロジェクトにプラグインを追加する場合の推奨ディレクトリ構成を以下に示す。
# 例: QML/C++プロジェクト
.opencode/
├── plugins/
│ ├── build-notify.ts # CMakeビルド結果通知プラグイン
│ ├── qml-hot-reload.ts # QMLホットリロード検知プラグイン
│ └── env-protection.ts # 環境変数保護プラグイン
└── package.json # 依存関係の定義
プラグインの作成方法
基本的なプラグイン
最もシンプルなプラグインの例を以下に示す。
以下に示すプラグインは、セッション作成時にログを出力するだけの基本的な実装である。
- ファイルの配置場所の例
- .opencode/plugins/hello.ts
import { Plugin } from "opencode/plugin"
export const HelloPlugin: Plugin = async ({ client }) => {
client.app.log("info", "HelloPlugin: 読み込み完了")
return {
"session.created": async ({ session }) => {
client.app.log("info", `新しいセッションが作成されました: ${session.id}`)
},
"session.deleted": async ({ session }) => {
client.app.log("info", `セッションが削除されました: ${session.id}`)
}
}
}
TypeScript / JavaScriptモジュール
OpenCodeのプラグインは、TypeScript または JavaScriptで記述できる。
TypeScriptを使用すると、型チェックによる安全性が向上するため推奨される。
TypeScriptプラグインの例を以下に示す。
import { Plugin, tool } from "opencode/plugin"
import { z } from "zod"
export const FullExamplePlugin: Plugin = async ({ client, directory }) => {
// 初期化処理
const startTime = Date.now()
client.app.log("info", "プラグイン初期化中...")
return {
"session.created": async ({ session }) => {
client.app.log("info", `セッション開始: ${session.id}`)
},
"session.idle": async ({ session }) => {
const elapsed = Date.now() - startTime
client.app.log("info", `セッションがアイドル状態になりました (経過時間: ${elapsed}ms)`)
},
"session.deleted": async ({ session }) => {
// 状態のクリーンアップ
client.app.log("info", `セッション終了: ${session.id}`)
},
"tool.execute.before": async ({ tool, args }) => {
client.app.log("debug", `ツール実行前: ${tool.name}`)
}
}
}
利用可能なフック
セッションフック
セッションのライフサイクルに関連するフックである。
| フック名 | 説明 | 用途 |
|---|---|---|
session.created |
セッションが新規作成された時 | 初期化処理、ログ記録 |
session.updated |
セッション情報が更新された時 | 状態の同期 |
session.idle |
セッションがアイドル状態になった時 | 通知送信、リソース解放 |
session.deleted |
セッションが削除された時 | クリーンアップ処理 (重要) |
session.status |
セッションのステータスが変化した時 | ステータス監視 |
session.compacted |
セッションがコンパクションされた時 | コンパクション後の処理 |
session.deleted フックでの状態クリーンアップは、メモリリーク防止のために特に重要である。
ファイルフック
メッセージとメッセージパーツに関連するフックである。
| フック名 | 説明 |
|---|---|
message.updated |
メッセージが更新された時 |
message.removed |
メッセージが削除された時 |
message.part.updated |
メッセージパーツが更新された時 |
message.part.removed |
メッセージパーツが削除された時 |
ツールフック
ツールの実行に関連するフックである。
ツールフックを使用すると、ツール実行前後に処理を追加したり、実行を制御したりできる。
| フック | 説明 |
|---|---|
tool.execute.before |
ツール実行前に呼び出される。 入力値の検証や変更が可能である。 throw でツール実行を中断できる。
|
tool.execute.after |
ツール実行後に呼び出される。 ツールの出力結果に対して後処理を行える。 |
ツールフックの使用例を以下に示す。
"tool.execute.before": async ({ tool, args }) => {
// 特定のツールの実行前に検証を行う
if (tool.name === "bash" && args.command.includes("rm -rf")) {
throw new Error("危険なコマンドの実行を拒否しました")
}
},
"tool.execute.after": async ({ tool, args, result }) => {
// ツール実行後にログを記録する
client.app.log("info", `ツール実行完了: ${tool.name}`)
}
コマンドフック
LLMへのリクエストに関連するフックである。
| フック | 説明 |
|---|---|
chat.params |
LLMに送信するパラメータを変更できる。温度設定やシステムプロンプトの動的変更に使用する。 |
chat.message |
LLMから受信したメッセージに対応する処理を行う。 |
シェルフック
シェルコマンドの実行に関連するフックである。
| フック | 説明 |
|---|---|
chat.params |
LLMに送信するパラメータを変更できる。 temperature設定やシステムプロンプトの動的変更に使用する。 |
chat.message |
LLMから受信したメッセージに対応する処理を行う。 |
shell.env フックの使用例を以下に示す。
"shell.env": async ({ env }) => {
return {
...env,
MY_PROJECT_API_URL: "https://api.example.com",
MY_PROJECT_ENV: "development"
}
}
LSPフック
Language Server Protocol に関連するフックである。
| フック | 説明 |
|---|---|
lsp.diagnostics |
LSPの診断情報 (エラーや警告) が更新された時に呼び出される。 コード品質の監視や自動修正処理に使用する。 |
下表に、その他の主要なフックを示す。
| フック | 説明 |
|---|---|
permission.ask |
権限確認ダイアログが表示される前に呼び出される。 |
permission.replied |
権限確認に対してユーザが返答した後に呼び出される。 |
auth |
カスタム認証プロバイダを実装する時に使用する。 |
カスタムツールの作成
プラグインでは tool() ヘルパー関数を使用してカスタムツールを定義できる。
カスタムツールを定義すると、LLMがそのツールを呼び出してタスクを実行できるようになる。
ツールの基本構造
カスタムツールの基本構造を以下に示す。
import { Plugin, tool } from "opencode/plugin"
export const CustomToolPlugin: Plugin = async ({ client }) => {
const myTool = tool({
name: "my_custom_tool",
description: "このツールの説明。LLMがいつ使用するかを判断するために使用される。",
parameters: {
input: tool.schema.string().describe("処理する入力テキスト"),
count: tool.schema.number().describe("繰り返し回数")
},
execute: async (args, context) => {
// ツールの処理を実装する
const result = args.input.repeat(args.count)
return { output: result }
}
})
return {
tools: [myTool]
}
}
引数スキーマ (Zod)
カスタムツールの引数スキーマはZodベースのヘルパーを使用して定義する。
利用可能なスキーマ型を以下に示す。
| スキーマ型 | 説明 | 使用例 |
|---|---|---|
tool.schema.string() |
文字列型 | ファイルパス、テキスト入力 |
tool.schema.number() |
数値型 | カウント、タイムアウト値 |
tool.schema.boolean() |
真偽値型 | フラグ、スイッチ |
tool.schema.enum([...]) |
列挙型 | 選択肢から1つを選ぶ引数 |
tool.schema.optional(...) |
省略可能な型 | 必須でない引数をラップする |
各スキーマ型に .describe() を連結することで、LLMへの説明を追加できる。
説明は詳細に記述するほど、LLMがツールを正しく使用しやすくなる。
parameters: {
path: tool.schema.string().describe("操作対象のファイルパス (絶対パスで指定)"),
mode: tool.schema.enum(["read", "write", "append"]).describe("ファイル操作のモード"),
encoding: tool.schema.optional(tool.schema.string()).describe("文字エンコーディング (省略時はUTF-8)")
}
複数ツールのエクスポート
1つのプラグインから複数のカスタムツールをエクスポートするには、tools フィールドに配列で指定する。
return {
tools: [toolA, toolB, toolC]
}
コンテキストアクセス
execute 関数の第2引数 context から、実行時の情報にアクセスできる。
| プロパティ | 説明 |
|---|---|
context.sessionID |
現在のセッションID |
context.messageID |
現在のメッセージID |
context.directory |
現在の作業ディレクトリ |
context.worktree |
ワークツリー情報 |
context.agent |
実行中のエージェント情報 |
context.signal |
キャンセル用のAbortSignal |
context.signal を使用することにより、長時間処理の途中でキャンセルに対応できる。
プラグインの実用例
環境変数保護
機密ファイル (環境変数ファイル、認証情報ファイル等) へのアクセスを禁止するプラグインの実装例を以下に示す。
- ファイルの配置場所の例
- .opencode/plugins/env-protection.ts
import { Plugin } from "opencode/plugin"
export const EnvProtection: Plugin = async ({ client }) => {
const sensitivePatterns = [/\.env/, /credentials/, /\.secret/]
return {
"tool.execute.before": async ({ tool, args }) => {
if (tool.name === "read" && sensitivePatterns.some(p => p.test(args.path))) {
throw new Error("Access denied to sensitive files")
}
}
}
}
このプラグインは、read ツールが機密ファイルにアクセスしようとした時に例外をスローして処理を中断する。
セッション通知
セッションがアイドル状態になった時にログを出力するプラグインの実装例を以下に示す。
この例を応用することで、外部の通知サービスへの連携も実現できる。
- ファイルの配置場所の例
- .opencode/plugins/notification.ts
import { Plugin } from "opencode/plugin"
export const NotificationPlugin: Plugin = async ({ client }) => {
return {
"session.idle": async ({ session }) => {
client.app.log("info", "Session completed")
// ここに外部通知サービスへのAPI呼び出し等を追加できる
}
}
}
カスタムツール定義
プロジェクト固有のカスタムツールを定義するプラグインの実装例を以下に示す。
この例では、指定したファイルのメタデータ (行数、サイズ等) を取得するツールを定義している。
- ファイルの配置場所の例
- .opencode/plugins/custom-tools.ts
import { Plugin, tool } from "opencode/plugin"
import { stat, readFile } from "fs/promises"
export const CustomToolsPlugin: Plugin = async ({ client }) => {
const fileInfoTool = tool({
name: "get_file_info",
description: "指定したファイルのメタデータ (行数、ファイルサイズ等) を取得する",
parameters: {
path: tool.schema.string().describe("情報を取得するファイルのパス")
},
execute: async (args, context) => {
const stats = await stat(args.path)
const content = await readFile(args.path, "utf-8")
const lines = content.split("\n").length
return {
size: stats.size,
lines: lines,
modified: stats.mtime.toISOString()
}
}
})
return {
tools: [fileInfoTool]
}
}
依存関係の管理
プラグインで外部npmパッケージを使用する場合は、.opencode/package.jsonファイル に依存関係を定義する。
{
"name": "opencode-plugins",
"version": "1.0.0",
"dependencies": {
"axios": "^1.6.0",
"zod": "^3.22.0"
},
"devDependencies": {
"typescript": "^5.3.0",
"@types/node": "^20.0.0"
}
}
OpenCodeの起動時に bun install コマンドが自動的に実行されるため、手動でインストールコマンドを実行する必要はない。
依存関係の管理に関する注意事項を以下に示す。
- package.jsonファイル は、必ず .opencode/ディレクトリ に配置する。
- プロジェクトルートの package.jsonファイル とは別ファイルである。
- Bunが使用されるため、npm、yarn、pnpmとは異なる場合がある。
- Bunに対応したパッケージを使用することを確認する。
- TypeScriptを使用する場合は、型定義パッケージ (@types/*) も依存関係に含める。
推奨される事柄
エラーハンドリング
プラグインのフック内では、適切なエラーハンドリングを実装する。
エラーが発生した場合でも、OpenCodeの動作が停止しないように注意する。
"session.created": async ({ session }) => {
try {
await initializeSession(session.id)
}
catch (error) {
client.app.log("error", `セッション初期化エラー: ${error}`)
// エラーを再スローしないことで、OpenCodeの動作を継続させる
}
}
セッション削除時のクリーンアップ
セッションごとに状態を保持する場合は、session.deleted フックで必ずクリーンアップを行う。
クリーンアップを怠るとメモリリークの原因となる。
export const StatefulPlugin: Plugin = async ({ client }) => {
const sessionState = new Map<string, any>()
return {
"session.created": async ({ session }) => {
sessionState.set(session.id, { startTime: Date.now() })
},
"session.deleted": async ({ session }) => {
// 必ずクリーンアップする
sessionState.delete(session.id)
}
}
}
ログ出力
プラグイン内のログ出力は console.log() ではなく、client.app.log() を使用する。
client.app.log() を使用することにより、OpenCodeのログシステムと統合されて適切に管理される。
// 正しい方法
client.app.log("info", "処理完了")
client.app.log("error", "エラーが発生しました")
client.app.log("debug", "デバッグ情報")
// 避けるべき方法
console.log("処理完了")
その他のベストプラクティス
- TypeScriptを使用して型安全性を確保する。
- TypeScriptの型チェックにより、ランタイムエラーを事前に防止できる。
- 公式フックのみを使用する。
- 非公式・内部フックは将来のバージョンで変更される可能性がある。
- 大規模なプラグインはモジュールに分割する。
- 機能ごとにファイルを分割して保守性を高める。
- プラグインの初期化処理は軽量に保つ。
- 起動時の重い処理はOpenCodeのレスポンス性に影響する可能性がある。
トラブルシューティング
プラグインが読み込まれない場合
プラグインが認識されない場合は、以下の項目を確認する。
配置ディレクトリの確認
プラグインファイルが正しいディレクトリに配置されているか確認する。
- プロジェクト固有
- .opencode/plugins/
- グローバル
- ~/.config/opencode/plugins/
ファイル拡張子の確認
プラグインファイルの拡張子が .ts または .js であることを確認する。
他の拡張子のファイルは自動読み込みの対象外である。
ログレベルの設定
OpenCodeのログレベルを DEBUG に設定することにより、詳細な読み込み情報を確認できる。
OPENCODE_LOG_LEVEL=DEBUG opencode
メモリリークが発生する場合
セッション削除時のクリーンアップが実装されているか確認する。
session.deleted フック内で、セッションに紐付いた全ての状態を削除しているか確認する。
"session.deleted": async ({ session }) => {
// Map、Set、その他のデータ構造からセッションのデータを削除する
mySessionData.delete(session.id)
myCache.delete(session.id)
}
依存関係の問題が発生する場合
外部パッケージが見つからないエラーが発生した場合は、以下を確認する。
- package.jsonファイル が .opencode/ディレクトリ に配置されているか確認する。
- プロジェクトルートではなく、
.opencode/直下に配置する必要がある。
- プロジェクトルートではなく、
bun installが正常に実行されたか確認する。- 手動で
bun installを実行して、エラーメッセージを確認する。
- 手動で
cd .opencode && bun install
プラグインの処理が期待通りに動作しない場合
- デストラクチャリングの記述方法を確認する。
- コンテキストは単一パラメータとしてデストラクチャリングする必要がある。
- 正しい記述方法:
async ({ client, project }) => { ... }
- フック名のスペルミスを確認する。
- フック名が誤っていると処理が呼び出されない。
- 公式ドキュメントでフック名を確認する。
throwの使用状況を確認する。tool.execute.beforeで例外をスローした場合、ツールの実行が中断される。- 意図しない
throwがないか確認する。
プラグインマーケットプレイス
OpenCodeはプラグインマーケットプレイス機能を提供しており、コミュニティが提供するプラグインを簡単にインストールできる。
マーケットプレイスからのプラグイン追加
マーケットプレイスからプラグインを追加するには、以下のコマンドを使用する。
# マーケットプレイスにプラグインを追加
/plugin marketplace add <マーケットプレイス名>/<プラグイン名>
# 例: Microsoft Docs MCPを追加
/plugin marketplace add microsoftdocs/mcp
プラグインのインストール
追加したマーケットプレイスからプラグインをインストールするには、以下のコマンドを使用する。
# プラグインをインストール
/plugin install <plugin-name>@<marketplace-name>
# 例: Microsoft Docsプラグインをインストール
/plugin install microsoft-docs@microsoft-docs-marketplace
Microsoft Docs MCPの設定例
Microsoft Docs MCPを使用すると、OpenCodeからMicrosoftおよびAzureの公式ドキュメントにアクセスできる。
公式ドキュメントを検索し、コードサンプルを取得し、詳細な技術情報を参照できる。
# Microsoft Docs MCPをマーケットプレイスに追加
/plugin marketplace add microsoftdocs/mcp
# Microsoft Docs プラグインをインストール
/plugin install microsoft-docs@microsoft-docs-marketplace
よく使用されるプラグイン
OpenCodeのエコシステムには多くのコミュニティプラグインが存在する。
使用される頻度の高い便利なプラグインをカテゴリ別に示す。
認証関連プラグイン
認証関連のプラグインを使用すると、APIクレジットの代わりに既存のサブスクリプションを使用できる。
| プラグイン名 | 説明 | opencode.jsonの設定 |
|---|---|---|
| opencode-openai-codex-auth | ChatGPT Plus/Proのサブスクリプションを使用してOpenAI Codexバックエンドを利用する。 OAuth認証をサポートする。 |
"opencode-openai-codex-auth"
|
| opencode-gemini-auth | 既存のGeminiプランを使用してGoogleアカウントで認証する。 API課金の代わりにGeminiプランを使用できる。 |
"opencode-gemini-auth"
|
| opencode-antigravity-auth | Antigravityの無料モデルを使用してAPI課金なしでモデルを利用する。 GeminiおよびAnthropicモデルに対応する。 |
"opencode-antigravity-auth"
|
| opencode-google-antigravity-auth | Google Antigravity OAuthを使用する拡張版。 Google検索サポートと堅牢なAPI処理を提供する。 |
"opencode-google-antigravity-auth"
|
開発環境プラグイン
開発環境を拡張するプラグインである。
| プラグイン名 | 説明 | opencode.jsonの設定 |
|---|---|---|
| opencode-daytona | Daytonaサンドボックス内でOpenCodeセッションを自動実行する。 Git同期とライブプレビュー機能を提供する。 |
"opencode-daytona"
|
| opencode-devcontainers | 複数ブランチのdevcontainer分離を実現する。 シャロークローンと自動割り当てポートをサポートする。 |
"opencode-devcontainers"
|
| opencode-morph-fast-apply | Morph Fast Apply APIを使用した高速なコード編集を実現する。 10,500+ tokens/secの編集速度と遅延編集マーカーを提供する。 |
"opencode-fast-apply"パッケージ名が異なる |
| opencode-type-inject | ファイル読み込み時にTypeScript/Svelteの型を自動注入する。 型参照ツールを提供する。 |
"@nick-vi/opencode-type-inject"スコープ付きパッケージ |
エージェント・オーケストレーションプラグイン
AIエージェントの動作を拡張・調整するプラグインである。
| プラグイン名 | 説明 | opencode.jsonの設定 |
|---|---|---|
| opencode-background-agents | Claude Codeスタイルのバックグラウンドエージェントを提供する。 非同期委任とコンテキスト永続化をサポートする。 |
"@zenobius/opencode-background"パッケージ名が異なる |
| oh-my-opencode | バックグラウンドエージェント、LSP/AST/MCPツール、厳選されたエージェントを提供する。 詳細は専用ページを参照のこと。 |
"oh-my-opencode"
|
| micode | 構造化されたブレインストーム→計画→実装のワークフローを提供する。 セッション継続性とサブエージェントオーケストレーションをサポートする。 |
"micode"
|
| opencode-workspace | バンドルされたマルチエージェントオーケストレーションハーネスを提供する。 16コンポーネントを1つのインストールで利用できる。 |
npmに未公開 |
通知・モニタリングプラグイン
セッション状態の通知や使用状況の追跡を行うプラグインである。
| プラグイン名 | 説明 | opencode.jsonの設定 |
|---|---|---|
| opencode-notify | タスク完了時のネイティブOS通知を提供する。 バックグラウンドタスクの完了を通知する。 |
"opencode-notify"
|
| opencode-notificator | デスクトップ通知とサウンドアラートを提供する。 OpenCodeセッションの状態変化を通知する。 |
npmに未公開 |
| opencode-notifier | 権限、完了、エラーイベントのデスクトップ通知とサウンドアラートを提供する。 | "@mohak34/opencode-notifier"スコープ付きパッケージ |
| opencode-wakatime | Wakatimeを使用してOpenCodeの使用状況を追跡する。 コーディング時間の自動記録を行う。 |
"opencode-wakatime"
|
| opencode-quota | プロバイダー間のクォータとトークン使用量を追跡する。 自動トースト通知とスラッシュコマンドを提供する。 |
"opencode-quota"
|
その他のユーティリティプラグイン
その他の便利なプラグインである。
| プラグイン名 | 説明 | opencode.json設定 |
|---|---|---|
| opencode-helicone-session | リクエストグループ化のためのHeliconeセッションヘッダーを自動注入する。 API使用状況の分析に使用する。 |
"opencode-helicone-session"
|
| opencode-dynamic-context-pruning | トークン使用量を最適化する。 古いツール出力をコンテキストから削除する。 |
"@tarquinen/opencode-dcp"スコープ付きパッケージ |
| opencode-supermemory | Supermemoryを使用してセッション間の永続メモリを提供する。 長期的なコンテキスト保持を実現する。 |
"opencode-supermemory"
|
| opencode-agent-memory | Lettaエージェントにインスパイアされた永続的な自己編集可能メモリブロックを提供する。 エージェントの記憶を保持する。 |
"opencode-agent-memory"
|
| opencode-direnv | セッション開始時にdirenv環境変数を自動的に読み込む。 Nix flakesとの相性が良い。 |
npmに未公開 |
| opencode-scheduler | launchd (Mac) または systemd (Linux) を使用して定期的なジョブをスケジュールする。 cron構文をサポートする。 |
"opencode-scheduler"
|
| opencode-websearch-cited | 対応プロバイダーのネイティブウェブ検索サポートを追加する。 Google groundedスタイルの引用付き検索を提供する。 |
"opencode-websearch-cited"
|
| opencode-md-table-formatter | LLMが生成したMarkdownテーブルを整形する。 テーブルの可読性を向上させる。 |
"@franlol/opencode-md-table-formatter"スコープ付きパッケージ |
| opencode-shell-strategy | 非対話型シェルコマンドの指示を提供する。 TTY依存操作によるハングを防止する。 |
npmに未公開 |
プラグインのインストール方法
プラグインをインストールするには、opencode.jsonファイル の plugin フィールドにパッケージ名を指定する。
{
"$schema": "https://opencode.ai/config.json",
"plugin": [
"opencode-wakatime",
"opencode-notify",
"@sveltejs/opencode"
]
}
スコープ付きnpmパッケージ (例: @sveltejs/opencode) もサポートされている。
公式エコシステムリソース
OpenCodeのエコシステムに関する情報は、以下のリソースから入手できる。
- OpenCodeの公式エコシステムページ
- 公式にリストされたプラグインとプロジェクトを確認できる。
- awesome-opencode GitHubリポジトリ
- コミュニティによって管理される厳選リスト
- プラグイン、テーマ、エージェント、リソースが含まれる。
- opencode.cafe
- コミュニティ駆動のマーケットプレイス
- 拡張機能、プラグイン、ツールを閲覧・共有できる。
opencode-auto-resume
opencode-auto-resumeは、LLMセッションがタイムアウトやエラーで停止した時に自動的に復旧させるプラグインである。
ストリームが停止したセッションやツール呼び出しを生テキストとして出力してしまう状態、幻覚ループ、サブエージェント終了後に親セッションがビジーのままになる孤児親状態等を検出して、ユーザ介入なしで回復させる。
主な機能
opencode-auto-resumeが提供する主な機能を以下に示す。
- ストール回復
- LLMからの応答ストリームが48秒以上停止した時に、自動的に continue プロンプトを送信して再開する。
- 試行回数は指数関数的バックオフで制御され、最大3回まで再開を試みる。
- 再開時は最後のセッションメッセージから agent、model、provider を抽出して、ユーザが選択した設定を保持する。
- ツール呼び出しの生テキスト検出
- モデルがXML形式のツール呼び出し (
<tool>...</tool>) を生テキストとして出力した場合に検出する。 - 検出時には専用の回復プロンプトを送信して、ツールを実際に実行させる。
- モデルがXML形式のツール呼び出し (
- 幻覚ループ検出
- 同じ壊れた出力を繰り返し生成している状態を検出する。
- 10分以内に3回以上 continue が必要になった場合、リクエストを中断してクリーンな状態から再開する。
- 孤児親セッション検出
- サブエージェントが終了したにも関わらず親セッションがビジーのまま固定される問題を検出する。
- ビジーカウントが1より大きい状態から1に減少し、15秒経過しても変化がない場合に回復処理を行う。
- ESC取消の検出
- ユーザが[ESC]キーでリクエストをキャンセルした場合は、以後の自動再開を行わない。
npm版のインストール (推奨)
npmパッケージとして公開されているopencode-auto-resumeは、パッケージマネージャーでインストールして opencode.json / opencode.jsonc ファイルに登録する。
プラグインをインストールする。
npm install opencode-auto-resume
インストール後、opencode.json / opencode.jsonc ファイルの plugin フィールドにパッケージ名を追加する。
{
"$schema": "https://opencode.ai/config.json",
"plugin": [
"opencode-auto-resume"
]
}
オプションを指定する場合は、[プラグイン名, オプションオブジェクト] の配列形式で登録する。
{
"plugin": [
[
"opencode-auto-resume",
{
"chunkTimeoutMs": 45000,
"gracePeriodMs": 3000,
"maxRetries": 3
}
]
]
}
GitHub版のインストール
GitHubリポジトリから直接取得する場合は、OpenCodeのグローバルプラグインディレクトリにクローンしてビルドする。
グローバルプラグインディレクトリにクローンする。
git clone https://github.com/Mte90/opencode-auto-resume.git ~/.config/opencode/plugins/opencode-auto-resume
プラグインディレクトリに移動する。
cd ~/.config/opencode/plugins/opencode-auto-resume
依存関係をインストールしてビルドする。
bun install bun run build
ビルド後、opencode.json / opencode.jsonc ファイルの plugin フィールドにビルド済みのエントリポイントを絶対パスで指定する。
{
"plugin": [
[
"file:///home/<ユーザ名>/.config/opencode/plugins/opencode-auto-resume/dist/index.js",
{
"chunkTimeoutMs": 45000,
"maxRetries": 3
}
]
]
}
更新する場合は、クローンしたディレクトリに移動して、以下に示すコマンドを実行する。
cd ~/.config/opencode/plugins/opencode-auto-resume git pull bun run build
設定方法
opencode-auto-resumeの動作は、opencode.json / opencode.jsonc ファイルの plugin フィールドで指定したオプションオブジェクトによって調整できる。
設定オプション
| オプション名 | デフォルト値 | 説明 |
|---|---|---|
chunkTimeoutMs |
45000 | ストリームが停止したと判断するまでの無通信タイムアウト (ミリ秒) |
gracePeriodMs |
3000 | 回復処理を実行する前に待つ猶予時間 (ミリ秒) |
checkIntervalMs |
5000 | タイマ監視のポーリング間隔 (ミリ秒) |
maxRetries |
3 | 自動再開を試行する最大回数 |
baseBackoffMs |
1000 | 初回再試行までの待ち時間 (ミリ秒) |
maxBackoffMs |
8000 | バックオフの上限時間 (ミリ秒) |
subagentWaitMs |
15000 | 孤児親セッションと判断するまでの待ち時間 (ミリ秒) |
loopMaxContinues |
3 | 幻覚ループ検出のウィンドウ内での最大 continue 回数 |
loopWindowMs |
600000 | 幻覚ループ検出のウィンドウ時間 (ミリ秒、デフォルト10分) |
動作確認
プラグインが正常に読み込まれているかは、OpenCodeの起動ログで確認できる。
OPENCODE_LOG_LEVEL=DEBUG opencode
以下に示すようなログが出力されれば、プラグインは正常に動作している。
opencode-auto-resume ready. timeout=45000ms...
実際の動作確認としては、セッションを48秒以上アイドル状態にすると自動的に continue が送信される。
ログに Stream stall や Ready-to-continue pattern detected が出力されていれば、回復処理が実行されている。
回復動作が多すぎる場合は chunkTimeoutMs の値を大きくし、反応が遅い場合は checkIntervalMs の値を小さくするとよい。
ただし、[ESC]キーでキャンセルしたセッションは自動再開の対象外となる。
参考リンク