---
metadata:
  - name: generator
    content: Diplodoc Platform v5.54.5
  - property: og:type
    content: article
  - property: article:section
    content: Платформа плагинов
  - property: og:title
    content: Как устроена платформа плагинов
  - property: article:tag
    content: Техническая инструкция
alternate:
  - https://yandex.ru/support/tracker/en/plugins/common.md
  - https://yandex.ru/support/tracker/ru/plugins/common.md
  - href: ru/plugins/common.md
    type: text/markdown
    title: Markdown version
  - href: ../llms.txt
    type: text/markdown
    title: llms.txt
---
> **Documentation Index:** Fetch the complete configuration index at https://yandex.ru/support/tracker/ru/llms.txt


# Как устроена платформа плагинов

Плагин — это отдельное фронтовое приложение на JavaScript, которое запускается в iframe внутри приложения Трекера. Для его разработки предоставляется SDK. Приоритетным считается использование React. Также существует библиотека на чистом JavaScript, которая позволяет не привязываться к React.

Платформа покрывает полный жизненный цикл плагинов: предоставляет инструменты разработки и отладки, версионирования и публикации, а также репозиторий для хранения плагинов. Администраторы могут устанавливать, обновлять и отключать плагины, контролируя их доступность для пользователей и контекстов.

## Выполнение плагина в iframe {#iframe}

Интерфейсная часть плагинов представляет собой статику, которая размещена на серверах Трекера. Она выполняется в изолированном iframe на безкуковом домене, которому запрещено почти всё, включая любые сетевые запросы. Поэтому всё общение с сервисами Яндекса, публичным API Трекера и внешним миром осуществляется через SDK.

## SDK {#sdk}

Работа с Трекером осуществляется с помощью [SDK](https://yandex.ru/support/tracker/ru/plugins/tools/index.md#sdk), который подключается как библиотека. SDK предоставляет методы взаимодействия на уровне пользовательского интерфейса, [методы для работы с публичным API Трекера](https://yandex.ru/support/tracker/ru/plugins/publicApi.md) и [хранилище данных плагина](https://yandex.ru/support/tracker/ru/plugins/storage.md).

SDK поставляется двумя npm-пакетами:

- [**core**](https://yandex.ru/support/tracker/ru/plugins/tools/sdk/core.md) — API-клиент и базовые примитивы интеграции (JS/TS).
- [**react**](https://yandex.ru/support/tracker/ru/plugins/tools/sdk/react.md) — React-обертки над core для удобной разработки UI.

## CLI {#cli}

[CLI](https://yandex.ru/support/tracker/ru/plugins/tools/cli.md) — это консольная утилита в виде NPM пакета, которая обеспечивает весь жизненный цикл плагина: создание, отладка, проверка и публикация.

## UI-компоненты {#ui-components}

[Библиотека UI-компонентов](https://yandex.ru/support/tracker/ru/plugins/components/index.md) в стилистике Трекера, доступных для использования в плагинах.

## Манифест {#manifest}

Манифест — это файл `manifest.json` в корне проекта. Он описывает плагин, запрашиваемые разрешения и точки интеграции с Трекером.

### JSON Schema {#manifest-schema}

При создании проекта CLI добавляет рядом с манифестом файл `manifest.schema.json` и указывает его в поле `$schema`:

```json
{
  "$schema": "./manifest.schema.json"
}
```

Редактор кода использует схему для проверки манифеста, автодополнения и показа допустимых значений. CLI проверяет манифест по встроенной схеме, даже если поле `$schema` отсутствует. Не редактируйте `manifest.schema.json` вручную. Чтобы обновить локальную схему и остальные файлы шаблона, выполните команду `weavix up`.

Ограничения и списки допустимых значений могут меняться. Проверяйте их в `manifest.schema.json` текущего проекта.

### Поля манифеста {#manifest-fields}

#|
|| **Поле** | **Тип** | **Обязательное** | **Описание** ||
|| `$schema` | `string` | Нет | Путь к JSON Schema. CLI добавляет значение `./manifest.schema.json` ||
|| `manifest_version` | `number` | Нет | Версия формата манифеста. CLI добавляет значение `1` ||
|| `supported_services` | `string[]` | Нет | Сервисы, в которых работает плагин. Для плагина Трекера укажите `["tracker"]` ||
|| `slug` | `string` | Да | Уникальное имя плагина из строчных латинских букв, цифр и дефисов. Длина — от 3 до 63 символов ||
|| `id` | `string` | Нет | Идентификатор плагина на платформе. CLI добавляет его при регистрации во время первой отправки командой `submit`. Не задавайте поле вручную ||
|| `version` | `string` | Да | Версия плагина в формате SemVer, например `1.2.0` ||
|| `name` | `object` | Да | Название на русском и английском языках в полях `ru` и `en`. Длина каждого значения — от 1 до 30 символов ||
|| `description` | `object` | Да | Описание на русском и английском языках в полях `ru` и `en`. Длина каждого значения — от 1 до 255 символов ||
|| `support` | `object[]` | Да | Непустой список контактов поддержки. Каждый объект содержит `type` со значением `email` и адрес длиной до 100 символов в поле `value` ||
|| `permissions` | `object` | Да | [Разрешения](#permissions), необходимые плагину. В объекте обязательно поле `data` ||
|| `slots` | `object` | Нет | [Точки интеграции](https://yandex.ru/support/tracker/ru/plugins/slots/index.md) плагина с интерфейсом сервисов ||
|| `categories` | `string[]` | Нет | [Категории](https://yandex.ru/support/tracker/ru/plugins/publish.md#category), по которым плагин отображается в каталоге ||
|| `docsUrl` | `string` | Нет | Адрес [справки плагина](https://yandex.ru/support/tracker/ru/plugins/publish.md#docs) ||
|| `homepage` | `string` | Нет | Адрес сайта плагина с протоколом HTTP или HTTPS ||
|| `license` | `string` | Нет | Идентификатор лицензии длиной до 32 символов, например `MIT` или `Apache-2.0` ||
|| `keywords` | `string[]` | Нет | Уникальные ключевые слова для поиска плагина. Длина каждого значения — до 30 символов ||
|| `whatsnew` | `string` | Нет | Описание изменений в версии длиной до 300 символов ||
|| `externalHost` | `string` | Нет | HTTPS-адрес, с которого загружается интерфейс плагина. Использование внешнего хоста требует согласования с командой Трекера ||
|#

### Настройка слотов {#manifest-slots}

Плагин может использовать несколько точек интеграции. Для каждой точки укажите:

- `entrypoint` — путь к входному HTML-файлу;
- `title` — название элемента интерфейса на русском и английском языках;
- `contextLevel` — уровень данных, доступных плагину:
    - `basic` — идентификатор текущей сущности и базовые метаданные;
    - `full` — полный объект сущности, например все поля задачи;
- `description` — необязательное описание на русском и английском языках;
- `icon` — необязательный объект с путем к значку в поле `url`. Используется в слоте `dock`.

Используйте `full`, только если плагину необходим полный объект сущности.

Поле `slots` не является обязательным по формату манифеста, но для проверки и публикации проекта необходимо настроить хотя бы один слот.

```json
"slots": {
  "tracker": {
    "issue.action": [
      {
        "entrypoint": "index.html",
        "contextLevel": "basic",
        "title": {
          "ru": "Мой плагин",
          "en": "My Plugin"
        }
      }
    ]
  }
}
```

## Разрешения {#permissions}

В манифесте укажите только те разрешения, которые необходимы плагину. Объект `permissions` содержит следующие поля:

- `data` — обязательный массив разрешений на работу с данными Трекера. Разрешения имеют формат `tracker:<ресурс>:read` для чтения и `tracker:<ресурс>:write` для изменения данных. Например, `tracker:issues:read` позволяет читать задачи, `tracker:issues:write` — изменять их, а `tracker:attachments:write` — загружать вложения. Актуальный список допустимых значений приведен в `manifest.schema.json`;
- `device` — доступ к возможностям устройства пользователя. Допустимые значения: `clipboard-write`, `microphone`, `camera`, `geolocation`, `web-share` и `allow-downloads`. Если это предусмотрено браузером, пользователь должен дополнительно разрешить доступ к выбранной возможности;
- `ui` — дополнительные действия в интерфейсе Трекера. Добавляйте такое разрешение, только если оно указано в описании используемого метода SDK;
- `external` — домены внешних API и параметры авторизации. Прямые запросы к таким API из плагина запрещены: их выполняет прокси платформы. Подробнее см. в разделе [Внешние API](https://yandex.ru/support/tracker/ru/plugins/externalApi.md#manifest).

{% note warning "Уровень доступа" %}

Разрешение в манифесте не расширяет права пользователя. Все действия выполняются от имени текущего пользователя и в пределах выданных ему прав.

{% endnote %}

## Хранилище данных плагинов {#plugin-data-storage}

Платформа предоставляет единое хранилище данных плагинов и API для работы с ним, которое поддерживает два режима:

- **Контекстное хранение** [Скоро] — данные привязываются к конкретной сущности Трекера и уровню гранулярности (`organization`, `user`, `queue`, `portfolio`, `project`, `issue`, `issue-comment`). Это подходит для настроек и состояния, зависящих от организации, пользователя, очереди или конкретного тикета. Контекст хранения не обязан совпадать с контекстом установки плагина.

- **Key-value режим** — данные хранятся как пары `key → value` в namespace плагина. Это подходит для простых конфигураций и служебных данных, где важнее быстрый доступ по ключу, чем привязка к доменной сущности.

В обоих режимах API покрывает чтение/запись/обновление/удаление данных, поддерживает контроль конкурентных изменений (версионирование/optimistic locking) и хранит `pluginVersion` для управляемых миграций данных при обновлении плагина.

Подробнее о текущей реализации хранилища и его API — в разделе [Хранилище данных плагина](https://yandex.ru/support/tracker/ru/plugins/storage.md).

## Доступ к внешним API (OAuth и прокси) {#external-api-access}

Платформа предоставляет безопасный механизм интеграций с внешними сервисами: прокси платформы для выполнения HTTP-запросов и сервис-секретницу для хранения OAuth-токенов.

- **Прокси платформы** — единая точка для вызовов внешних API от имени плагина. Плагин отправляет параметры запроса: URL, метод, заголовки, тело. Платформа выполняет запрос на бекенде и возвращает результат. Доступ ограничивается декларативно (allowlist доменов). Платформа блокирует небезопасные направления (приватные сети/localhost, неразрешенные редиректы), ведет аудит и применяет rate limit по `pluginId` и организации.

- **OAuth и Секретница** — платформа берет на себя OAuth-flow и хранение токенов: access/refresh токены сохраняются в секретнице и никогда не попадают в iframe плагина. Токены поддерживаются в двух контекстах: **`user`** (персональные) и **`organization`** (общие для организации, создаются администратором). При запросах через прокси платформа автоматически подставляет нужный токен, а при истечении — выполняет refresh на бекенде или сигнализирует о необходимости переавторизации.

Подробнее о том, как вызывать внешние API из плагина, — в разделе [Внешние API](https://yandex.ru/support/tracker/ru/plugins/externalApi.md).

## Точки интеграции (слоты) {#integration-points}

Место, в котором плагин будет открыт, а также механизм его вызова (кнопка или как часть формы, например), определяется слотом. Слот указывается в манифесте.

Доступные слоты и детали их использования описаны в разделе [Точки интеграции](https://yandex.ru/support/tracker/ru/plugins/slots/index.md).

## Контекст запуска плагина {#launch-context}

Контекст запуска плагина определяется слотом, в котором он находится и содержит следующую информацию:

- Текущая тема Трекера
- Текущий язык Трекера
- Контекст слота — данные из окружения страницы, в которой запущен плагин. Например, в слоте `issue.action` вернется информация по открытому тикету. Формат контекста максимально приближен к типам публичного API.

### Уровни контекста слота {#context-levels}

Уровень контекста задается параметром `contextLevel` в описании слота в `manifest.json` и определяет, какие данные будут доступны плагину через [`useTrackerPluginContext`](https://yandex.ru/support/tracker/ru/plugins/tools/sdk/react.md#usetrackerplugincontext).

#### basic {#basic}

Доступен только идентификатор текущей сущности и базовые метаданные:

```typescript
type BasicContext = {
    /** Идентификатор текущей сущности */
    entityId: string;
    /** Дополнительная базовая информация о сущности.
     *  Например, для комментария здесь будет идентификатор родительского тикета. */
    entityMeta?: Record<string, string>;
};
```

Используйте `basic`, если плагину достаточно знать идентификатор сущности — это более легкий вариант без лишней нагрузки.

#### full {#full}

Полный контекст с живыми данными сущности. Формат совпадает с типами публичного API. Например, для слота `issue.action` — полный объект `Issue`. Данные актуальны на момент открытия плагина.

Используйте `full`, только если плагину действительно нужны полные данные сущности.

{% note warning "Выбор уровня контекста" %}

Запрашивайте только тот уровень контекста, который реально нужен плагину. При отсутствии необходимости в полных данных сущности используйте `basic`.

{% endnote %}
