プラグインマニフェストとパッケージング
Manifest v2 の plugin JAR を定義し、リリース用ファイルとして配布する。
すべての Turboism plugin JAR には、次の場所に descriptor が正確に 1 つあります。
META-INF/turboism/plugin.jsonRuntime が受け入れるのは schema version 2 だけです。Version 1 はロードも自動 upgrade もされません。
最小 manifest
{
"format": "turboism.plugin.meta",
"schemaVersion": 2,
"id": "dev.example.plugin.hello",
"name": "Hello Plugin",
"version": "0.1.0",
"description": "Minimal Turboism plugin lifecycle example.",
"entrypoints": [
"dev.example.plugin.HelloPlugin"
],
"turboismApi": "[0.1.0,0.2.0)",
"authors": [
{ "name": "Example Author" }
],
"license": "MIT",
"website": "https://example.org/hello-plugin",
"resources": [],
"i18n": {
"baseName": "META-INF/turboism/i18n/messages",
"locales": []
},
"dependencies": [],
"permissions": [],
"capabilities": [],
"environment": {
"requiresCubism": false,
"ui": "none"
}
}Entrypoint のルール
各 entrypoint は次を満たさなければなりません。
- 同じ plugin JAR 内に存在する。
- public である。
TurboismPluginまたは subinterface を実装する。- public no-argument constructor を公開する。
複数の entrypoint は、1 つの plugin identity、descriptor、ClassLoader、PluginContext、DisposableScope、permission set、configuration namespace、storage namespace、resource、localization declaration を共有します。
construct/init/enable: manifest order
disable/shutdown: reverse manifest orderconstruct、initialization、enablement の途中で failure が発生すると、JAR 全体が rollback されます。
Dependency
{
"id": "dev.example.plugin.base",
"version": "[1.0.0,2.0.0)",
"type": "required",
"ordering": "after",
"reason": "Uses the base plugin contract."
}typeはrequiredまたはoptionalです。orderingはnone、before、またはafterです。- dependency ID は reverse-domain syntax を使います。
- version range は現在の Turboism version-range grammar を使います。
dependency record は resolution と ordering を制御します。別 plugin の private implementation package を public Java dependency にするものではありません。
Permission
各 permission record には、既知の ID、application または user scope、空でない reason が含まれます。
{
"id": "turboism.action.register",
"scope": "application",
"reason": "Registers the Hello action."
}plugin が呼び出す SDK service に必要な permission だけを宣言してください。permission は Provider の availability を保証せず、operation validation を迂回するものでもありません。
Resource と localization
Resource root は / で終わる正規化済みの相対 prefix です。
"resources": ["icons/"],
"i18n": {
"baseName": "META-INF/turboism/i18n/messages",
"locales": ["base", "en", "zh_Hans"]
}その場合、JAR には次が含まれていなければなりません。
icons/hello.png
META-INF/turboism/i18n/messages.properties
META-INF/turboism/i18n/messages_en.properties
META-INF/turboism/i18n/messages_zh_Hans.properties宣言した root と catalog は存在しなければなりません。通常の class 以外の resource は、宣言された root に属していなければなりません。path traversal、absolute path、backslash、空の segment、undeclared resource は拒否されます。
build と検証
repository 内の plugin module では、次を実行します。
./gradlew :plugins:hello:test :plugins:hello:jar validatePluginMeta \
--no-daemon --console=plainrepository は Java 17 を使用し、module のビルド結果を次の下に書き込みます。
build/worktree/<worktreeId>/<module>/libs/厳格な JAR 検証
JAR 自体がインストール成果物です。Runtime は選択された JAR を信頼できないローカル入力として扱い、次を検証します。
- 通常ファイルで、source chain にシンボリックリンクがなく、16 MiB 上限。
META-INF/turboism/plugin.jsonが正確に 1 つ。- descriptor の ID、version、API range の整合性。
- コピーされた SDK、Runtime、test、test-framework、Live2D class がない。
- native binary や installer payload がない。
- ネストされた JAR がない。
- 宣言された entrypoint、resource root、i18n catalog が存在する。
- 未宣言の通常 resource がない。
マネージドインストールは検証済み JAR をステージングし、Cubism の再起動後に適用します。任意の ZIP や JAR の名前を変更して plugin を作成しないでください。常に Gradle build が生成した JAR を配布してください。