Перейти к основному содержимому

Манифест плагина

Манифест плагина (plugin.json) — единый источник истины для плагина: идентичность, точки входа, запрошенные разрешения и объявленные возможности.

Структура пакета

Пакет .stplugin — это ZIP-архив, содержащий plugin.json в корне, файлы точек входа, на которые он ссылается, и любые ресурсы. Хост проверяет архив до установки чего-либо: traversal-пути, симлинки, исполняемые нагрузки и лимиты размеров — всё отклоняется.

Поля манифеста

{
"id": "author.plugin-name",
"name": "Plugin Name",
"version": "1.0.0",
"apiVersion": 2,
"engines": { "neotavern": "^0.1.0" },
"frontend": "dist/frontend.js",
"backend": "dist/backend.mjs",
"styles": "dist/plugin.css",
"permissions": ["chat.read", "ui.messageActions", "network:api.example.com"],
"i18n": { "ru": "locales/ru.json", "de": "locales/de.json" }
}

Основные поля:

  • id — идентификатор в reverse-DNS-нотации, например author.plugin-name. Он уникален среди всех установленных плагинов и стабилен при обновлениях.
  • name — человекочитаемое имя, показываемое в менеджере плагинов.
  • version — семантическая версия (major.minor.patch). Она участвует в сравнении версий и сбросе кэша.
  • apiVersion — версия API SDK, на которую нацелен плагин. Текущая версия — 3; версия 2 остаётся по умолчанию, пока новый рантайм не выйдет в продакшн.
  • engines — ограничения совместимости, такие как neotavern: "^0.1.0".
  • frontend — относительный путь к браузерной ESM-точке входа.
  • backend — относительный путь к ESM-точке входа Node.js.
  • styles — необязательная таблица стилей плагина.
  • i18n — соответствие кода локали относительному пути к файлам переводов JSON.

Разрешения

Массив permissions — устаревший плоский список из SDK v2. Новые манифесты должны вместо этого объявлять ограниченные возможности через requiredCapabilities и optionalCapabilities:

{
"requiredCapabilities": [
{ "name": "chat.read" },
{ "name": "network", "scope": "api.example.com" }
],
"optionalCapabilities": [{ "name": "lorebook.read" }]
}

requiredCapabilities — возможности, без которых плагин не может работать; optionalCapabilities — те, без которых он может деградировать. Пользователь подтверждает каждую запрошенную возможность при установке. Добавление новых разрешений при обновлении требует повторного согласия — см. Разрешения.

Устаревшие точки входа

{
"legacy": {
"frontend": "legacy/main-window.js",
"backend": "legacy/server.mjs"
}
}

Блок legacy указывает на доверенные точки входа совместимости для существующих расширений SillyTavern. Пакеты, использующие любую из точек входа, должны запросить разрешение legacy.trusted, а UI показывает более строгое предупреждение во время согласия. Безопасный режим никогда не загружает устаревшие точки входа. О том, чем это отличается от нативных плагинов, см. Песочница.

OAuth-клиенты

Плагины, подключающиеся к внешнему сервису, могут объявлять публичные OAuth 2.0-клиенты, использующие поток авторизационного кода с PKCE:

{
"authClients": [
{
"serviceId": "com.example.idp",
"name": "Example IdP",
"authorizationUrl": "https://idp.example.com/oauth/authorize",
"tokenUrl": "https://idp.example.com/oauth/token",
"clientId": "neotavern-author.plugin-name",
"scopes": ["profile.read"]
}
]
}

Разрешены только публичные клиенты: clientSecret запрещён, потому что код плагина выполняется в песочнице. Конечные точки должны быть HTTPS, с исключением для loopback по обычному HTTP для локальных провайдеров идентичности при разработке. Изменение дескриптора требует переустановки пакета.

Поля воркеров и подписи

Расширенные манифесты могут объявлять дополнительные модули:

  • workers — модули точек входа относительно пакета, которые плагин может порождать как изолированные вычислительные воркеры. Порождание необъявленной точки входа отклоняется.
  • publisher и signature — подпись пакета. keyId — это отпечаток ed25519:<hex> подписывающего публичного ключа, а signature — подпись Ed25519 в base64 над каноническим манифестом. Они задаются инструментом сборки плагинов и никогда не пишутся вручную.

Функция validateManifest в SDK проверяет каждое поле, а генерируемый справочник Plugin SDK документирует точный тип PluginManifest.