Контракт манифеста (v1)
Манифест задаётся в ryntExtensionViteConfig({ manifest }) и попадает в dist/manifest.json.
При сборке и загрузке лаунчер парсит манифест и валидирует contributes.rynt (схема v1 без requiresRegistries).
Обязательные и общие поля
| Поле | Описание |
|---|---|
id | Стабильный id (@rynt/my-pack) |
name, version, description | Метаданные (version может подтянуться из package.json при сборке) |
main | Entry после сборки (index.js) |
engines.rynt | Semver-диапазон версии лаунчера |
extensionApi | Версия контракта платформы: "1" (целое, не semver). См. 08-extension-api-versioning.md |
version | Semver пакета (релиз, автообновление с каталога) |
extensionApi
{
"extensionApi": "1"
}- Одна поддерживаемая версия API: 1. В коде хоста:
EXTENSION_API_VERSION = 1. - Не использовать
^1.0.0/1.0.0— только major как строка. - Политика: API только расширяется, обратная совместимость сохраняется; лаунчер обновляется чаще расширений.
- Проверка в лаунчере мягкая:
required <= host→ грузим;required > host→ предупреждение (опционально не грузим в strict); отсутствие поля → считаем"1". - Подробнее и автообновление расширений по
version: 08-extension-api-versioning.md.
extensionDependencies
{
"extensionDependencies": {
"@rynt/chats-calls": "^0.0.1"
}
}- Ключ —
manifest.idзависимости. - Значение — semver range; лаунчер проверяет совместимость с установленной версией зависимости.
- Задаёт порядок выполнения
setup(топологическая сортировка + проверка циклов).
Важно для 0.0.x: ^0.0.1 означает >=0.0.1 <0.0.2 (только патч внутри той же «минорной» тройки). Версия зависимости 0.0.2 такой диапазон не удовлетворяет. Для «0.0.1 и любой более новой 0.0.x» используйте >=0.0.1 или явный ^0.0.2.
Дополнительно резолвер может добавить implied зависимости: если расширение в extendsRegistries ссылается на чужой registryId, владелец должен загрузиться раньше (см. 03-launcher-resolution.md).
contributes.rynt.declaresRegistries
Реестры, которые создаёт это расширение (для себя и для других).
{
"contributes": {
"rynt": {
"declaresRegistries": [
{
"id": "@rynt/chats-calls.message-types",
"title": "Типы сообщений чата",
"description": "Тело сообщения по ключу payload.type"
}
]
}
}
}| Поле | Обязательно | Описание |
|---|---|---|
id | да | registryId (уникален среди declares в одном манифесте) |
title | нет | Для каталога / UI |
description | нет | Для каталога / UI |
Не путать с пополнением: объявление не означает, что расширение не будет писать в свой же реестр (владелец часто регистрирует ключи text, build, … в setup).
contributes.rynt.extendsRegistries
Реестры, которые расширение пополняет, и какими ключами (для резолва, каталога и кнопки «установить слот»).
Формат (группировка по registryId):
{
"contributes": {
"rynt": {
"extendsRegistries": [
{
"registryId": "@rynt/chats-calls.message-types",
"keys": ["demo_ping"]
},
{
"registryId": "core.nav",
"keys": ["chats.main"]
}
]
}
}
}| Правило валидации | |
|---|---|
registryId непустой | |
keys — массив, минимум один элемент | |
| ключи уникальны внутри одного объекта | |
один registryId не дублируется в массиве extendsRegistries |
Семантика: «это расширение заявляет, что при установке оно заполнит указанные слоты». Фактическая запись в runtime — через register в setup; расхождение манифест ↔ runtime — предупреждение в dev (не блокер в лаунчере).
requiresRegistries
Удалено из v1. Не использовать и не поддерживать в парсере. Используйте только extendsRegistries.
Примеры тестовых расширений
@rynt/chats-calls
declaresRegistries:@rynt/chats-calls.message-types,@rynt/chats-calls.input-toolbarextendsRegistries: те же реестры с ключами встроенных типов +core.page/core.nav/ …
@rynt/chats-message-sample
{
"extensionDependencies": {
"@rynt/chats-calls": "^0.0.1"
},
"contributes": {
"rynt": {
"extendsRegistries": [
{
"registryId": "@rynt/chats-calls.message-types",
"keys": ["demo_ping"]
},
{
"registryId": "@rynt/chats-calls.input-toolbar",
"keys": ["demo_ping"]
}
]
}
}
}@rynt/optifine-marketplace
Только расширяет встроенный реестр (без declaresRegistries):
{
"contributes": {
"rynt": {
"extendsRegistries": [
{
"registryId": "core.modProvider",
"keys": ["optifine"]
}
]
}
}
}Соответствует коду: useModProviderRegistry().register('optifine', provider, …).
@rynt/quilt-loader / @rynt/json-editor
{
"extendsRegistries": [
{ "registryId": "core.loader", "keys": ["quilt"] }
]
}{
"extendsRegistries": [
{ "registryId": "core.fileEditor", "keys": ["@rynt/json-editor/editor"] }
]
}(точные строки ключей должны совпадать с register(...) в setup.)
Нормализация при загрузке
После parseRyntManifestJson:
applyValidatedRyntContributesToManifest(manifest)— в discovery лаунчера и при emitdist/manifest.jsonв@rynt/extension-build.- При ошибке — расширение не загружается / не публикуется в каталог.