プラグイン開発者向けドキュメント
AnBoWork デスクトップ アプリ用のプラグインを構築します。AI 用の新しいツールを追加し、セッションの隣に独自のパネルをドッキングし、システム通知を送信し、新しいファイル形式を解析します。開始するには、manifest.json 1 つとエントリ スクリプト 1 つで十分です。
01概要
AnBoWork プラグインは、プレーンな Node.js プログラムです。インストール後、アプリはスタンドアロンの子プロセス (純粋なノード、Electron API なし) としてフォークし、プロセス間メッセージを介して通信します。 SDK パッケージは必要ありません。必要なのはprocess.on('message')とprocess.send()だけです。
プラグインが実行できるすべてのことは、manifest.json で静的に宣言されます。プレインストール同意ページとマーケットプレイスのレビューにより、プラグイン コードを実行せずに、追加するツールと必要な権限を知ることができます。すべての UI (ツールバー アイコン、設定、コマンド パレット、コンテキスト メニュー) は、ホストによって宣言からレンダリングされます。プラグイン コードはメイン ウィンドウ内で実行されることはありません。ドッキング ビューとフローティング パネルのみが独自の HTML であり、独立したサンドボックス ページで実行されます。
機能の概要
| マニフェストフィールド | 能力 | ユーザーが目にする場所 |
|---|---|---|
tools | AI 用の呼び出し可能なツールを追加する | AI が会話の中で自動的に呼び出します。ツール呼び出しはセッションに表示されます |
views | セッションの右側のサイドバーにドッキングされた永続ビュー | セッションツールバーの追加アイコンにより、右側にページが開きます |
ui | スタンドアロンのフローティング ウィンドウ | プラグイン一覧の「⋯」メニューから開きます |
sessionAction | セッションツールバーの永続アクションアイコン | ワンクリックで指定したツールが実行されます |
configuration | 設定ページのエントリ | 設定 → プラグイン設定;値は呼び出しごとに渡されます |
commands | Ctrl/Cmd+K コマンド パレットのエントリ | コマンドパレット |
keybindings | グローバルキーボードショートカット | キーの組み合わせによりコマンドがトリガーされます |
menus | セッションのコンテキストメニュー項目 | セッション行の「⋯」/右クリック メニュー |
documentParsers | 入力ボックスにドロップされたファイルを解析します | ユーザーが一致するファイルをドロップすると自動的に呼び出されます |
activationEvents | アプリと一緒に始める | 見えない;バックグラウンドタイマーが必要なプラグイン用 |
permissions | 必要な権限を宣言する | プレインストール同意ページ |
02クイックスタート
最小限のプラグインに必要なファイルは 2 つだけです。
1.manifest.jsonを書く
2. エントリースクリプトを書く
3. アプリにインストールする
AnBoWork → トップバー「ツール」→「プラグイン」→右上隅の「ローカルにインストール」を開き、プラグイン フォルダー (またはその zip) を選択します。同意ページには、インストール前に宣言された権限とすべてのツールがリストされます。確認して有効にします。
4. 試してみる
どのセッションでも、AI に「プラグインにアリスに挨拶するよう依頼してください」と指示します。ツールの説明に基づいて、AI は say_hello を呼び出すことを決定し、呼び出しとその結果がセッションに表示されます。
03マニフェストフィールド
| 分野 | タイプ | 必須 | 説明 |
|---|---|---|---|
id | string | はい | リバースドメインスタイル、例: com.example.my-plugin。文字、数字、ドット、ハイフンのみ。一度作成すると不変です。同じ ID を再度インストールすると、再インストールとして扱われます。 |
name | string | はい | プラグイン名。 description とともにコンテキストとしてモデルに供給されるため、英語を推奨します。 |
version | string | はい | セマンティックバージョン。マーケットプレイスはそれを使用して更新を検出します。 |
description | string | はい | プラグインの機能を説明する 1 文 (英語)。 |
author | string | いいえ | 著者。 |
readme | string | いいえ | マーケットプレイスの詳細ページに表示される長い形式の説明は、Markdown をサポートしています。その中の画像は https URL である必要があります。zip にバンドルされているファイルへの相対パスはサポートされていません。 |
icon | string | いいえ | マーケットプレイスのリストと詳細ページに表示されるアイコン — zip にバンドルされているファイルへの相対パス (例: icon.png)。 SVG ではなく、少なくとも 128×128 の PNG である必要があります。 |
main | string | はい | プラグイン フォルダーを基準としたエントリ スクリプト。 .. フォルダーをエスケープすることはできません。 |
permissions | string[] | はい | network / filesystem / notifications;空の配列である可能性があります。 「権限モデル」を参照してください。 |
tools | object[] | はい | ツール宣言。空の配列である可能性があります。 「ツールと通話プロトコル」を参照してください。 |
documentParsers | object[] | いいえ | ファイル解析機能。 |
ui | object | いいえ | フローティングパネル:{ entry, title } |
views | object[] | いいえ | ドッキングされたビュー:{ id, title, icon, entry, width? } |
sessionAction | object | いいえ | ツールバー アイコン。プラグインごとに最大 1 つ。 |
configuration | object[] | いいえ | 設定エントリのリスト。 |
commands | object[] | いいえ | コマンドパレットのエントリ。 |
keybindings | object[] | いいえ | ショートカット。 command は、commands[] のエントリの tool を参照する必要があります。参照しない場合、インストールは拒否されます。 |
menus | object | いいえ | 現時点では、session/context の場所のみが利用可能です。 |
activationEvents | string[] | いいえ | 今のところonStartupFinishedのみです。 |
テキストの言語規則
マニフェスト内のテキストには 2 つの対象読者がいます。 モデルの場合: name、description、tools[].description、tools[].parameters.*.description。これらを英語で書きましょう。モデルは英語のツールの説明を理解し、パラメータをより確実に入力します。 人: tools[].summary (同意ページの 1 行要約)、ui.title、views[].title、sessionAction.tooltip、configuration[].label、commands[].title、menus 内のtitle。これらをターゲット ユーザーの言語で記述します。
04権限モデル
permissions は、コードが実際に行うことを正直に反映する必要があります。プレインストール同意ページにはそれぞれの同意ページがリストされているため、ユーザーはインストールするかどうかを決定できます。マーケットプレイスのレビューでは、宣言とコードもチェックされます。
| 許可 | 申告しなければならない場合 | ホストの扱い方 |
|---|---|---|
filesystem | ユーザー ファイルの読み取りまたは書き込み (プロジェクト コードの読み取り、ドキュメントの生成、ホーム フォルダーへのデータの保存) | ユーザーに示されるインフォームド・コンセント。 |
network | ネットワーク リクエストの実行 (サードパーティ API、ダウンロード) | ユーザーに示されるインフォームド・コンセント。 |
notifications | show_notification リバース RPC 経由でシステム通知を表示する | Enforced: 宣言なしで呼び出すと、host_error が返され、通知は表示されません。 |
filesystem と network は現時点では同意レベルの宣言であり、実行時サンドボックスではありません。ホストは fs や fetch をインターセプトしません。だからこそ、宣言は正直でなければなりません。過少宣言したプラグインはマーケットプレイスのレビューで拒否され、発見された時点でユーザーの信頼を失います。どちらも過剰に宣言しないでください (未使用の権限はユーザーを躊躇させます)。プライバシーとデータ
context.cwd はユーザーのプロジェクト フォルダーであり、ソース コードと機密性の高い構成が含まれる場合があります。ツールの引数にはユーザーの会話が含まれる場合があります。機能で必要な場合を除き、このデータをネットワーク経由で送信しないでください。送信する場合は、何を誰に送信するかを description と summary に明記してください。プラグイン自体の永続データは、プラグイン ID に基づいて名前が付けられたユーザーのホーム フォルダー内のファイルに保存されるため、アンインストール時に見つけやすくなります。
05ツールと通話プロトコル
宣言
| 分野 | 説明 |
|---|---|
name | 小文字とアンダースコアで構成されるツール名。アプリ全体で一意です (組み込みツールや他のプラグインのツールとともにモデルに登録されます)。 |
description | モデルの説明 (英語)。ツールが何をするか、ツールを呼び出す必要がある場合と呼び出すべきではない場合にユーザーが言うことの 3 つのことを述べます。これは、AI がプラグインを使用するかどうかを決定する最も重要なフィールドです。 |
summary | 同意ページに表示される人間が判読できる 1 行の概要。オプションですが、強くお勧めします。それ以外の場合は、代わりに切り詰められた説明が表示されます。 |
parameters | すべてのプロパティに description が付いている標準の JSON スキーマ オブジェクト。モデルはそこから引数を入力し、ホストは追加の検証なしでそれらを渡すため、コード内の必須フィールドを確認してください。 |
renderAs | オプション。現在は checklist のみ: ホストは呼び出し引数からの todos 配列をチェックリスト カードとしてレンダリングします。以下を参照してください。 |
tools[] で宣言されたツール名のみを呼び出すことができます。sessionAction.tool、commands[].tool、および menus 内の tool フィールドは、インストール時に空でない文字列であるかどうかのみチェックされます。ホストは、名前が tools[] で宣言されているかどうかを検証しません が、ボタン、ショートカット、またはメニュー項目がトリガーされたときにその名前で呼び出しをディスパッチします。したがって、純粋に UI によってトリガーされたアクションは、tools[] に表示されることなく、完全に独自の index.js で処理できます。ただし、AI はそれを確認したり呼び出したりすることはできません。クリックとチャット リクエストに応じて動作する AI の両方で同じアクションをトリガーできるようにしたい場合は、tools[] でも同じ名前を宣言して、両方のエントリ ポイントが 1 つのハンドラーを共有するようにします。 UI のみを維持する場合は、宣言しないままにしておきます。完全に見えるようにするためだけにエントリを追加する必要はありません。メッセージプロトコル
ホストは call_tool を送信します。プラグインは、同じ requestId を含む tool_result または tool_error で応答する必要があります。 30 秒以内に応答がない呼び出しはタイムアウトになり、モデルはエラーを受け取ります。
content は、text ブロックと image ブロックのみを受け入れます (base64 data に mimeType を加えたイメージ)。他のタイプはドロップされます。 details は、モデルに決して供給されない任意の構造化データです。これはホスト UI レンダリングと独自のドッキング ビュー用です。
ファイル結果: ファイル カード
チェックリスト レンダリング: renderAs チェックリスト
適切な説明を書く
トリガーを命令文 (「ユーザーが…を要求したときにこれを呼び出す」) で記述し、除外項目を記述します (「… ではこれを呼び出さないでください」)。結果がファイルの場合は、生成されたと主張するのではなく、返されたファイル リンクを参照するようにモデルに依頼します。引数が外部生成 API に転送される場合は、どの言語で引数を使用するかを指定します。「ToDo の管理」などのワンライナーは避けてください。モデルはいつツールを使用すべきかわかりません。
06ドッキングされたビュー (ビュー)
ドッキング ビューは、セッションの右側のサイドバーにある永続的なページです。追加のアイコンがセッション ツールバーに表示され、開くと HTML が右側に表示されます。ページの状態 (スクロール位置、下書き) は、セッションの切り替えや折りたたみ/展開後も存続します。これは、VS Code のサイドバー ビューと同じセマンティクスです。
| 分野 | 説明 |
|---|---|
id | プラグイン内で一意です。 |
title | アイコンのツールチップ テキスト (人間が判読できる)。 |
icon | ホスト許可リストから選択します: git-branch、checklist。アプリ全体でアイコンの一貫性を保ちます。カスタム画像は受け付けられません。 |
entry | プラグインフォルダーを基準とした HTML ファイル。 |
width | オプションのデフォルトのパネル幅 (ピクセル単位)、240 ~ 640、デフォルトは 360。ユーザーはドラッグしてサイズを変更でき、サイズは記憶されます。 |
ページの実行時間
このページはサンドボックス (sandbox + contextIsolation、ノードなし、ホスト アプリ データへのアクセスなし) で実行され、window.pluginHost のいくつかのメソッドを通じてのみ独自のプラグイン プロセスと通信できます。独自のスタイルを持ち込んでください。以下の例のように、アプリの明暗スキームに従うことをお勧めします。
推奨パターン: 最初の読み込み時に、invoke() で独自のクエリ ツールの 1 つを呼び出し、details で構造化データを返すようにします。その後、ポーリングの代わりに ui_push を使用して、プラグイン プロセスからのすべての変更をプッシュします。 AI が会話内のデータを変更すると、パネルはすぐに更新されます。
07フローティングパネル (ui)
ui: { entry, title } ユーザーがプラグイン リストの「⋯」メニューから開くスタンドアロンのフローティング ウィンドウ (900×700) を宣言します。閉じると破壊されます。ページ環境と window.pluginHost API はドッキング ビューと同一であり、ui_push はフローティング パネルとドッキング ビューの両方に配信されます。時々開く大きなパネルに適しています。セッションの隣に置くコンテンツには views を使用します。
08セッションツールバーアイコン (sessionAction)
永続アイコンはプラグインごとに最大 1 つです。これをクリックすると、空の引数を指定して tool が呼び出されるため、このツールはパラメーターなしで意味のある処理を実行する必要があります。
| 分野 | 説明 |
|---|---|
tool | クリックで呼び出すツール。 |
icon | 許可リストに登録されたアイコン名。 |
tooltip | ホバーテキスト。 |
visibleTool | オプション。設定すると、レンダリング前に空の引数を指定して呼び出され、結果のブール値 details.visible によってアイコンが表示されるかどうかが決まります。 「現在のフォルダーは git リポジトリであるか」などの実行時チェックに役立ちます。 |
09設定(構成)
宣言されたエントリは、設定ページのプラグイン設定の下に表示されます。ホストは、ユーザーが変更した値を保存し、呼び出しが AI、ツールバー アイコン、またはパネルからのものであるかどうかに関係なく、call_tool (id によってキー設定され、defaultValue にフォールバック) ごとにそれらを context.config として渡します。それらを求める必要はありません。
| type | 次のようにレンダリングされます | デフォルト値のタイプ |
|---|---|---|
select | 単一選択リスト。オプションはoptionsToolからです | string |
boolean | トグルスイッチ | boolean |
string | テキスト入力、ブラーにコミット | string |
number | 数値入力 | number |
10コマンドパレット/ショートカット/コンテキストメニュー
3 つはすべて、「空の引数を使用してツールを呼び出す」ための異なるエントリ ポイントです。プラグインは複数を宣言できます。
| 分野 | 形 | 説明 |
|---|---|---|
commands | { tool, icon, title }[] | Ctrl/Cmd+K コマンド パレットに表示され、ユーザーが検索した後にトリガーされます。 |
keybindings | { command, key }[] | command は、commands[] のエントリの tool と等しくなければなりません。 key は mod+shift+g 表記を使用します。ここで、mod は macOS では Cmd、その他の場所では Ctrl です。他のショートカットとの競合は静的にチェックされないため、一般的ではない組み合わせを選択してください。 |
menus | { "session/context": { tool, icon, title }[] } | セッション行のメニューに追加されました。現時点ではこの場所のみが利用可能です。 |
11ドキュメントパーサー (documentParsers)
ユーザーがファイルを入力ボックスにドロップすると、ホストは有効なプラグインによって宣言されたパーサーを MIME タイプで検索し、ファイルの内容を Base64 として一致する toolName に渡します。これは AI が呼び出すことを決定したツールではないため、ではなく tools の下にパーサー ツールをリストしてください。そうしないと、AI 呼び出し可能なツールとして公開されます。
12リバース RPC (host_request)
プラグイン プロセスには Electron API がありません。実際のシステム機能が必要な場合、ホストに host_request を送信し、ホストは host_response または host_error で応答します。このチャンネルはcall_toolから完全に独立しています。ツール呼び出しの処理中またはタイマーから使用できます。
| capability | params | result | 前提条件 |
|---|---|---|---|
show_notification | { title, body?, viewId? } | { shown: true } / { shown: false, reason: "disabled" | "unsupported" } | notifications 権限が必要です。ユーザーが設定でデスクトップ通知をオフにした場合、エラーではなく無効を返します。 viewId がドッキング ビューの 1 つをポイントしている場合、通知をクリックするとアプリが前面に表示され、そのビューが展開されます。 |
render_pdf | { outputPath, title, content } | {} | コンテンツはマークダウンです。ホストは、内蔵レンダラーを使用して PDF を OutputPath にレンダリングします。 |
13ライフサイクル
| ステージ | 行動 |
|---|---|
| 始める | デフォルトでは遅延: アプリは起動されず、ツール (AI、ツールバー アイコン、パネル、コマンド、ドキュメント解析) の 1 つへの最初の呼び出し時にフォークされます。 activationEvents: ["onStartupFinished"] を宣言するプラグインは、アプリの起動終了直後に開始されます。これは、バックグラウンド タイマー (リマインダー、ポーリング) を必要とするプラグインにのみ使用し、通常のツール プラグインには使用しません。 |
| 居住者 | プロセスは開始されると存続し、ツール呼び出し全体で再利用されます。状態をメモリにキャッシュできますが、いつでも再起動できることを前提としています。 |
| クラッシュ | プロセスが予期せず終了した場合、ホストはすぐにプロセスを再起動し、その後 5 秒後と 15 秒後に再起動します。 3 回連続して失敗すると、「クラッシュ」とマークされ、再試行されなくなります。ユーザーはプラグイン ページでステータスを確認できます。実行中の呼び出しはすべてエラーを返します。 |
| 無効化/アンインストール/再インストール | プロセスは終了し、ドッキングされたビューとフローティング パネルは破棄されます。再インストールするとフォルダー全体が置き換えられます。 |
| ログ | stdout/stderr は、プラグイン ID がプレフィックスとしてアプリのログ ファイルに書き込まれます。デバッグにはプレーン console.log で十分です。 「デバッグと FAQ」を参照してください。 |
ELECTRON_RUN_AS_NODE=1 で始まり、cwd はプラグインのインストールフォルダーであり、Node のバージョンはアプリにバンドルされている Electron と一致します。グローバルにインストールされたパッケージに依存したり、npx が存在すると仮定したりしないでください。14パッケージ化と出版
包装
アーカイブ ルートにあるプラグイン フォルダーを manifest.json で ZIP 圧縮します。サードパーティの依存関係がある場合は、node_modules 全体を出荷するのではなく、最初に esbuild/webpack を使用してそれらを 1 つのファイルにバンドルします。
マーケットプレイスへの公開
AnBoWork → ツール → プラグイン → 「マーケットプレイス」タブ → 右上隅の「プラグインの公開」をクリックして、zip をアップロードします。提出物はレビューに入り、マニフェスト宣言がコード (特にアクセス許可) と一致するかどうかがチェックされます。承認されると、他のユーザーがマーケットプレイスでプラグインを見つけてインストールできるようになり、AI が必要と判断したときに、検証済みのプラグインをユーザーに自動的にインストールできます。
アップデート
version を押して再度公開します。アプリはインストールされているバージョンとマーケットプレイスのバージョンを比較し、更新するように求めます。再インストールすると、ユーザーの有効な状態と設定値が保持されます。
15完全な例: Todo クワドラント
実際に動作するプラグイン (トリミング済み): AI は Todo を追加および削除でき、右側のサイドバーにはリアルタイムで更新されるボードが表示され、システム通知リマインダーを送信できます。これら 3 つを連鎖させることで、ツール プロトコル、ドッキング ビュー プッシュ、およびリバース RPC がカバーされます。
16デバッグとよくある質問
| 症状 | 原因と修正 |
|---|---|
| インストール時にマニフェストの検証が失敗する | メッセージが示すように、各フィールドを「マニフェスト フィールド」テーブルと照合して確認します。ID 形式、main/entry に .. が含まれていてはならず、アイコンが許可リストに登録されている必要があり、キーバインド コマンドはコマンド内の既存のツールを指している必要があり、幅は 240 ~ 640 です。 |
| AI が私のツールを呼び出すことはありません | ほとんどの場合、description という問題が発生します。トリガーが不明瞭であるか、英語で書かれていないということです。 「適切な説明を書く」を参照してください。また、ツール名が他のツールと競合していないかも確認してください。 |
| 通話タイムアウト (30 秒) | エントリ スクリプトは tool_result で応答しませんでした。通常、requestId はエコーバックされないか、メッセージ type のスペルが間違っているか、スクリプトが起動時にスローされて終了しました。アプリログで、接頭辞 [plugin:your-id] が付いている行を探します。 |
| プラグインのステータスが「クラッシュ」と表示される | 3回連続スタート失敗。一般的には、パッケージが欠落していることを示す require です。プラグインフォルダー内でnode index.jsを実行すると再現されます。修正後、プラグイン ページでプラグインをオフにしてから再度オンに切り替えます。 |
| パネルが空白で開きます | entry パスが間違っているか、ページ上の JS エラーです。ページはノードの require なしでサンドボックス内で実行されます。 window.pluginHost のみが利用可能です。 |
| 通知が表示されない | 順番にチェックしてください: マニフェストは notifications を宣言します。結果は shown:false ではありません (ユーザーがデスクトップ通知をオフにしました)。 OS は AnBoWork からの通知を許可します。 |
| 設定値が読めない | 値は params ではなく、message.context.config[id] にあります。 |
ログファイルの場所
| OS | パス |
|---|---|
| macOS | ~/Library/Logs/AnBoWork/main.log |
| Windows | %USERPROFILE%\AppData\Roaming\AnBoWork\logs\main.log |