Документация разработчика плагинов
Создавайте плагины для настольного приложения AnBoWork: добавляйте новые инструменты для ИИ, закрепляйте собственную панель рядом с сеансом, отправляйте системные уведомления, анализируйте новые форматы файлов. Для начала достаточно одного файла Manifest.json и одного входного скрипта.
01Обзор
Плагин AnBoWork — это простая программа Node.js. После установки приложение разветвляет его как автономный дочерний процесс (чистый Node, без Electron API) и взаимодействует с ним посредством межпроцессных сообщений. Пакет SDK не требуется; все, что вам нужно, это process.on('message') и process.send().
Все, что может делать плагин, объявлено статически в manifest.json: страница согласия перед установкой и обзор рынка могут указать, какие инструменты он добавляет и какие разрешения ему необходимы, без запуска какого-либо кода плагина. Весь пользовательский интерфейс (значки панели инструментов, настройки, палитра команд, контекстные меню) отображается хостом из объявления; Код плагина никогда не запускается внутри главного окна. Только закрепленные представления и плавающие панели представляют собой ваш собственный HTML, и они выполняются на изолированных изолированных страницах.
Возможности с первого взгляда
| Поле манифеста | Возможность | Где пользователи это видят |
|---|---|---|
tools | Добавьте вызываемые инструменты для ИИ | ИИ автоматически вызывает их в разговоре; вызовы инструментов отображаются в сеансе |
views | Постоянное представление, закрепленное на правой боковой панели сеанса. | Дополнительный значок на панели инструментов сеанса открывает вашу страницу справа. |
ui | Отдельное плавающее окно | Открывается из меню «⋯» в списке плагинов. |
sessionAction | Значок постоянного действия на панели инструментов сеанса | Один клик запускает указанный вами инструмент |
configuration | Записи на странице настроек | Настройки → Настройка плагина; значения передаются при каждом вызове |
commands | Элементы палитры команд Ctrl/Cmd+K | Палитра команд |
keybindings | Глобальные сочетания клавиш | Комбинация клавиш запускает команду |
menus | Элементы контекстного меню сеанса | Меню «⋯» / контекстное меню в строке сеанса |
documentParsers | Анализ файлов, помещенных в поле ввода | Вызывается автоматически, когда пользователь удаляет соответствующий файл. |
activationEvents | Начни вместе с приложением | Невидимый; для плагинов, которым нужны фоновые таймеры |
permissions | Объявить необходимые разрешения | Страница согласия на предустановку |
02Быстрый старт
Минимальному плагину требуется всего два файла.
1. Напишите манифест.json
2. Напишите сценарий входа
3. Установите в приложение.
Откройте AnBoWork → верхняя панель «Инструменты» → «Плагины» → «Установить локально» в правом верхнем углу, затем выберите папку плагина (или ее zip-архив). На странице согласия перечислены заявленные разрешения и каждый инструмент перед установкой; подтвердите включение.
4. Попробуйте
В любом сеансе скажите ИИ «попросите плагин передать привет Алисе». На основании описания инструмента ИИ решает вызвать say_hello, и вызов и его результат появляются в сеансе.
03Поля манифеста
| Поле | Тип | Необходимый | Описание |
|---|---|---|---|
id | string | Да | Стиль обратного домена, например. com.example.my-plugin. Только буквы, цифры, точки и дефисы. Неизменяемый после создания; повторная установка того же идентификатора рассматривается как переустановка. |
name | string | Да | Название плагина. Вместе с description он передается в модель как контекст, поэтому рекомендуется использовать английский язык. |
version | string | Да | Семантическая версия; рынок использует его для обнаружения обновлений. |
description | string | Да | Одно предложение, описывающее, что делает плагин (на английском языке). |
author | string | Нет | Автор. |
readme | string | Нет | Полное описание, показанное на странице сведений о торговой площадке, поддерживает Markdown. Изображения внутри него должны иметь URL-адреса https — относительные пути к файлам, упакованным в zip-архив, не поддерживаются. |
icon | string | Нет | Значок, отображаемый в списке торговой площадки и на странице сведений — относительный путь к файлу, упакованному в zip-архив (например, icon.png). Должен быть PNG, а не SVG, не менее 128×128. |
main | string | Да | Скрипт входа относительно папки плагина. .. выход из папки не разрешен. |
permissions | string[] | Да | network/filesystem/notifications; может быть пустой массив. См. «Модель разрешений». |
tools | object[] | Да | Объявления инструментов; может быть пустой массив. См. «Инструменты и протокол вызовов». |
documentParsers | object[] | Нет | Возможность разбора файлов. |
ui | object | Нет | Плавающая панель:{ entry, title } |
views | object[] | Нет | Закрепленные представления:{ id, title, icon, entry, width? } |
sessionAction | object | Нет | Значок на панели инструментов, не более одного на каждый плагин. |
configuration | object[] | Нет | Список записей настроек. |
commands | object[] | Нет | Записи палитры команд. |
keybindings | object[] | Нет | Ярлыки. command должен ссылаться на tool записи в commands[], в противном случае установка будет отклонена. |
menus | object | Нет | На данный момент доступна только локация session/context. |
activationEvents | string[] | Нет | Пока только onStartupFinished. |
Языковые соглашения для текста
Текст в манифесте предназначен для двух аудиторий. Для модели : name, description, tools[].description, tools[].parameters.*.description. Напишите это на английском языке; модели понимают описания инструментов на английском языке и более надежно заполняют параметры. Для людей: tools[].summary (однострочное резюме на странице согласия), ui.title, views[].title, sessionAction.tooltip, configuration[].label, commands[].title и title внутри menus. Напишите их на языке ваших целевых пользователей.
04Модель разрешения
permissions должен честно отражать то, что на самом деле делает код. На странице согласия перед установкой перечислены все из них, чтобы пользователи могли решить, устанавливать ли их; Обзор рынка также проверяет декларацию на соответствие коду.
| Разрешение | Когда его необходимо объявить | Как к этому относится хозяин |
|---|---|---|
filesystem | Чтение или запись пользовательских файлов (чтение кода проекта, генерация документов, сохранение данных в домашней папке) | Информированное согласие, показываемое пользователю. |
network | Выполнение любого сетевого запроса (сторонние API, загрузки) | Информированное согласие, показываемое пользователю. |
notifications | Отображение системных уведомлений через обратный RPC show_notification | Enforced: вызов без объявления возвращает host_error и уведомление не отображается. |
filesystem и network в настоящее время являются декларациями уровня согласия, а не изолированной программной средой времени выполнения: хост не перехватывает fs или fetch. Именно поэтому декларации должны быть честными. Плагины с недостаточной декларацией отклоняются при проверке на рынке и теряют доверие пользователей при обнаружении. Не переусердствуйте (неиспользуемые разрешения заставляют пользователей колебаться).Конфиденциальность и данные
context.cwd — это папка проекта пользователя, которая может содержать исходный код и конфиденциальную конфигурацию; Аргументы инструмента могут содержать разговор пользователя. Не отправляйте эти данные по сети, если этого не требует функция. Когда вы это сделаете, укажите в description и summary, что и кому отправляется. Храните собственные постоянные данные плагина в файле в домашней папке пользователя, названном в честь идентификатора плагина, чтобы их можно было легко найти при удалении.
05Инструменты и протокол вызова
Декларация
| Поле | Описание |
|---|---|
name | Имя инструмента строчными буквами и подчеркиванием, уникальное для всего приложения (оно регистрируется в модели наряду со встроенными инструментами и инструментами других плагинов). |
description | Описание к модели (англ.). Укажите три вещи: что делает инструмент, что говорит пользователь, когда его следует вызывать и когда его нельзя вызывать. Это самое важное поле для определения того, использует ли ИИ ваш плагин. |
summary | Однострочное, понятное человеку резюме, отображаемое на странице согласия. Необязательно, но настоятельно рекомендуется; в противном случае вместо этого отображается усеченное описание. |
parameters | Стандартный объект схемы JSON с description для каждого свойства. Модель заполняет из нее аргументы, а хост передает их без дополнительной проверки, поэтому проверяйте обязательные поля в своем коде. |
renderAs | Необязательный; в настоящее время только checklist: хост отображает массив todos из аргументов вызова как карточку контрольного списка, см. ниже. |
tools[] — sessionAction.tool, commands[].tool, а поле tool внутри menus проверяется только на то, чтобы быть непустой строкой во время установки; хост не проверяет, что имя объявлено в tools[], и по-прежнему отправляет вызов под этим именем при срабатывании кнопки, ярлыка или пункта меню. Таким образом, действие, запускаемое исключительно пользовательским интерфейсом, может быть полностью обработано в вашем собственном index.js, даже не появляясь в tools[] — но тогда ИИ никогда не сможет его увидеть или вызвать. Если вы хотите, чтобы одно и то же действие запускалось как щелчком мыши, так и действием ИИ по запросу чата, объявите это же имя и в tools[], чтобы обе точки входа использовали один обработчик; если он предназначен только для пользовательского интерфейса, оставьте его необъявленным — нет необходимости добавлять запись только для того, чтобы она выглядела завершенной.Протокол сообщений
Хост отправляет call_tool; плагин должен ответить tool_result или tool_error, содержащим тот же requestId. Вызов без ответа в течение 30 секунд истекает, и модель получает сообщение об ошибке.
content принимает только блоки text и image (изображение в формате base64 data плюс mimeType); другие типы отбрасываются. details — произвольные структурированные данные, которые никогда не передаются в модель; он предназначен для рендеринга пользовательского интерфейса хоста и ваших собственных закрепленных представлений.
Результаты файла: карточки файлов
Контрольный список рендеринга: контрольный список renderAs
Написание хорошего описания
Опишите триггер в императиве («Вызовите это, когда пользователь просит…») и укажите исключения («Не вызывайте это для…»). Если результатом является файл, попросите модель сослаться на возвращенную ссылку на файл, а не заявлять, что она была сгенерирована. Если аргументы пересылаются во внешний API-интерфейс генерации, укажите, на каком языке они должны быть. Избегайте однострочных слов, таких как «управление задачами»; модель не будет знать, когда использовать инструмент.
06Закрепленные виды (представления)
Закрепленное представление — это постоянная страница на правой боковой панели сеанса: на панели инструментов сеанса появляется дополнительный значок, а при открытии справа отображается HTML-код. Состояние страницы (положение прокрутки, черновики) сохраняется при переключении сеансов и сворачивании/развертывании, та же семантика, что и представление боковой панели VS Code.
| Поле | Описание |
|---|---|
id | Уникальный в рамках плагина. |
title | Текст подсказки для значка (читабельный для человека). |
icon | Выберите из белого списка хостов: git-branch, checklist. Сохраняет единообразие значков во всем приложении; пользовательские изображения не принимаются. |
entry | HTML-файл относительно папки плагина. |
width | Необязательная ширина панели по умолчанию в пикселях: от 240 до 640, по умолчанию 360. Пользователи могут перетаскивать, чтобы изменить размер, и размер запоминается. |
Время выполнения страницы
Страница работает в «песочнице» (sandbox + contextIsolation, без Node, без доступа к данным хост-приложения) и может взаимодействовать со своим собственным процессом плагина только с помощью нескольких методов из window.pluginHost. Принесите свои собственные стили; рекомендуется следовать светлой/темной схеме приложения, как показано в примере ниже.
Рекомендуемый шаблон: при первой загрузке вызовите один из ваших собственных инструментов запросов с помощью invoke() и он вернет структурированные данные в details; после этого отправляйте каждое изменение из процесса плагина с помощью ui_push вместо опроса. Когда ИИ меняет данные в разговоре, панель немедленно обновляется.
07Плавающая панель (UI)
ui: { entry, title } объявляет отдельное плавающее окно (900×700), которое пользователи открывают из меню «⋯» в списке плагинов; он уничтожается при закрытии. Среда страницы и API window.pluginHost идентичны закрепленным представлениям, а ui_push доставляется как на плавающую панель, так и на закрепленные представления. Подходит для больших панелей, открываемых время от времени; используйте views для контента, который должен оставаться рядом с сеансом.
08Значок панели инструментов сеанса (sessionAction)
Не более одного постоянного значка для каждого плагина. Щелчок по нему вызывает tool с пустыми аргументами, так что инструмент должен сделать что-то значимое без параметров.
| Поле | Описание |
|---|---|
tool | Инструмент для вызова по клику. |
icon | Имя значка из белого списка. |
tooltip | Наведите текст. |
visibleTool | Необязательный. Если этот параметр установлен, он вызывается с пустыми аргументами перед рендерингом, и логическое значение details.visible в результате определяет, будет ли отображаться значок. Полезно для проверок во время выполнения, например «является ли текущая папка репозиторием git». |
09Настройки (конфигурация)
Объявленные записи отображаются в разделе конфигурации плагина на странице настроек. Хост сохраняет значения, измененные пользователем, и передает их как context.config при каждом call_tool (с помощью id, возвращаясь к defaultValue), независимо от того, исходит ли вызов от AI, значка панели инструментов или вашей панели. Вам никогда не придется их просить.
| type | Отображается как | Тип значения по умолчанию |
|---|---|---|
select | Список с одним выбором; варианты приходят из optionsTool | string |
boolean | Тумблер | boolean |
string | Ввод текста, зафиксированный при размытии | string |
number | Ввод номера | number |
10Палитра команд/ярлыки/контекстное меню
Все три являются разными точками входа для «вызова инструмента с пустыми аргументами»; плагин может объявить несколько.
| Поле | Форма | Описание |
|---|---|---|
commands | { tool, icon, title }[] | Отображается в палитре команд Ctrl/Cmd+K и активируется после того, как пользователь выполняет его поиск. |
keybindings | { command, key }[] | command должно равняться tool записи в commands[]. key использует обозначение mod+shift+g, где mod — это Cmd на macOS и Ctrl в другом месте. Конфликты с другими ярлыками не проверяются статически, поэтому выбирайте необычные комбинации. |
menus | { "session/context": { tool, icon, title }[] } | Добавлено в меню в строке сеанса. Пока доступна только эта локация. |
11Парсеры документов (documentParsers)
Когда пользователь помещает файл в поле ввода, хост ищет синтаксические анализаторы, объявленные включенными плагинами, по типу MIME и передает содержимое файла в формате base64 соответствующему toolName. Это не тот инструмент, который ИИ решает вызвать, поэтому не также укажите инструмент синтаксического анализатора в tools, иначе он будет представлен как инструмент, вызываемый ИИ.
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. Возвращает значение «disabled» вместо ошибки, когда пользователь отключил уведомления на рабочем столе в настройках. Когда viewId указывает на одно из закрепленных представлений, щелчок по уведомлению выводит приложение на передний план и расширяет это представление. |
render_pdf | { outputPath, title, content } | {} | контент — Markdown; хост визуализирует PDF-файл в выходной путь с помощью встроенного средства визуализации. |
13Жизненный цикл
| Этап | Поведение |
|---|---|
| Начинать | Ленивый по умолчанию: не запускается с приложением, разветвляется при первом вызове одного из ваших инструментов (ИИ, значок на панели инструментов, панель, команда, анализ документа). Плагины, объявляющие activationEvents: ["onStartupFinished"], запускаются сразу после завершения запуска приложения; используйте это только для плагинов, которым нужны фоновые таймеры (напоминания, опрос), а не для обычных плагинов инструментов. |
| Резидент | После запуска процесс остается активным и повторно используется при вызовах инструментов. Вы можете кэшировать состояние в памяти, но предполагайте, что его можно перезапустить в любое время. |
| Крушение | Если процесс неожиданно завершается, хост перезапускает его: сразу, затем через 5 и 15 секунд. После 3 неудач подряд он помечается как «сбой» и больше не повторяется; пользователи видят статус на странице плагина. Во время полета вызывает все возвращаемые ошибки. |
| Отключить/удалить/переустановить | Процесс завершается, а закрепленные виды и плавающие панели уничтожаются; при переустановке заменяется вся папка. |
| Журналы | Ваши stdout/stderr записываются в файл журнала приложения с префиксом идентификатора плагина. Для отладки достаточно обычного console.log; см. «Отладка и часто задаваемые вопросы». |
ELECTRON_RUN_AS_NODE=1, cwd — это папка установки плагина, а версия Node соответствует версии Electron, входящей в комплект приложения. Не зависьте от какого-либо глобально установленного пакета и не предполагайте, что npx существует.14Упаковка и издательское дело
Упаковка
Заархивируйте папку плагина с помощью manifest.json в корне архива. Если у вас есть сторонние зависимости, сначала объедините их в один файл с помощью esbuild/webpack вместо того, чтобы отправлять весь node_modules.
Публикация на торговой площадке
AnBoWork → Инструменты → Плагины → вкладка «Торговая площадка» → «Опубликовать плагин» в правом верхнем углу, затем загрузите zip-архив. Отправленные материалы проходят проверку, которая проверяет соответствие декларации манифеста коду (особенно разрешениям). После одобрения другие пользователи смогут найти и установить его на рынке, а ИИ может автоматически устанавливать проверенные плагины для пользователей, когда сочтет это необходимым.
Обновления
Нажмите version и опубликуйте снова. Приложение сравнивает установленную версию с версией из магазина и предлагает обновиться; при переустановке сохраняется включенное состояние пользователя и значения настроек.
15Полный пример: Todo Quadrant
Настоящий работающий плагин (обрезанный): ИИ может добавлять и удалять задачи, на правой боковой панели отображается доска, которая обновляется в реальном времени, и он может отправлять напоминания о системных уведомлениях. Объединение этих трех элементов охватывает протокол инструмента, отправку закрепленного представления и обратный RPC.
16Отладка и часто задаваемые вопросы
| Симптом | Причина и исправление |
|---|---|
| Проверка манифеста не удалась при установке | Проверьте каждое поле по таблице «Поля манифеста», поскольку в сообщении указано: формат идентификатора, основная/запись не должна содержать .., значок должен быть внесен в список разрешенных, команда привязок клавиш должна указывать на существующий инструмент в командах, ширина от 240 до 640. |
| ИИ никогда не вызывает мой инструмент | Практически всегда проблема description: триггер непонятен или написан не по-английски. См. «Написание хорошего описания». Также убедитесь, что имя инструмента не конфликтует с именем другого инструмента. |
| Тайм-аут звонка (30 с) | Сценарий входа не ответил tool_result. Обычно requestId не было возвращено, сообщение type написано с ошибкой или сценарий выдал ошибку при запуске и завершил работу. Найдите строки с префиксом [plugin:your-id] в журнале приложения. |
| Статус плагина показывает «разбился». | 3 неудачных старта подряд. Обычно require об отсутствующем пакете; запуск node index.js в папке плагина воспроизводит его. После исправления выключите и снова включите плагин на странице плагина. |
| Панель открывается пустая | Неправильный путь entry или ошибка JS на странице. Страница работает в песочнице без Node require; доступен только window.pluginHost. |
| Уведомление не появляется | Проверьте по порядку: в манифесте указано notifications; результат не shown:false (пользователь отключил уведомления на рабочем столе); ОС позволяет получать уведомления от AnBoWork. |
| Значения настроек не читаются | Значения указаны в message.context.config[id], а не в params. |
Расположение файла журнала
| ОС | Путь |
|---|---|
| macOS | ~/Library/Logs/AnBoWork/main.log |
| Windows | %USERPROFILE%\AppData\Roaming\AnBoWork\logs\main.log |