Documentos para desarrolladores de complementos
Cree complementos para la aplicación de escritorio AnBoWork: agregue nuevas herramientas para la IA, conecte su propio panel junto a una sesión, envíe notificaciones del sistema, analice nuevos formatos de archivo. Un manifest.json más un script de entrada es suficiente para comenzar.
01Descripción general
Un complemento AnBoWork es un programa Node.js simple. Después de la instalación, la aplicación la bifurca como un proceso secundario independiente (Nodo puro, sin API de Electron) y se comunica con ella a través de mensajes entre procesos. No se requiere ningún paquete SDK; todo lo que necesitas es process.on('message') y process.send().
Todo lo que puede hacer un complemento se declara estáticamente en manifest.json: la página de consentimiento de preinstalación y la revisión del mercado pueden indicar qué herramientas agrega y qué permisos necesita sin ejecutar ningún código de complemento. El host representa toda la interfaz de usuario (iconos de la barra de herramientas, configuraciones, paleta de comandos, menús contextuales) a partir de la declaración; El código del complemento nunca se ejecuta dentro de la ventana principal. Sólo las vistas acopladas y los paneles flotantes son su propio HTML y se ejecutan en páginas aisladas en un espacio aislado.
Capacidades de un vistazo
| campo manifiesto | Capacidad | Dónde lo ven los usuarios |
|---|---|---|
tools | Agregue herramientas invocables para la IA | La IA los llama automáticamente durante una conversación; Las llamadas a herramientas se muestran en la sesión. |
views | Vista persistente acoplada en la barra lateral derecha de la sesión | Un ícono adicional en la barra de herramientas de la sesión abre su página a la derecha |
ui | Ventana flotante independiente | Abierto desde el menú "⋯" en la lista de complementos |
sessionAction | Icono de acción persistente en la barra de herramientas de la sesión. | Un clic ejecuta la herramienta que especifiques |
configuration | Entradas en la página de configuración | Configuración → Configuración del complemento; los valores se pasan con cada llamada |
commands | Entradas de la paleta de comandos Ctrl/Cmd+K | paleta de comandos |
keybindings | Atajos de teclado globales | Una combinación de teclas activa un comando |
menus | Elementos del menú contextual de sesión | El menú "⋯"/clic derecho en una fila de sesión |
documentParsers | Analizar archivos colocados en el cuadro de entrada | Se llama automáticamente cuando el usuario suelta un archivo coincidente. |
activationEvents | Comience junto con la aplicación | Invisible; para complementos que necesitan temporizadores en segundo plano |
permissions | Declarar los permisos requeridos | Página de consentimiento de preinstalación |
02Inicio rápido
Un complemento mínimo necesita sólo dos archivos.
1. Escribe manifest.json
2. Escribe el guión de entrada.
3. Instalar en la aplicación
Abra AnBoWork → barra superior "Herramientas" → "Complementos" → "Instalar localmente" en la esquina superior derecha, luego seleccione la carpeta del complemento (o un archivo zip). Una página de consentimiento enumera los permisos declarados y todas las herramientas antes de la instalación; confirme para habilitar.
4. Pruébalo
En cualquier sesión, dígale a la IA "pídale al complemento que salude a Alice". Según la descripción de la herramienta, la IA decide llamar a say_hello y la llamada y su resultado aparecen en la sesión.
03Campos manifiestos
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
id | string | Sí | Estilo de dominio inverso, p. com.example.my-plugin. Sólo letras, dígitos, puntos y guiones. Inmutable una vez creado; instalar la misma identificación nuevamente se trata como una reinstalación. |
name | string | Sí | Nombre del complemento. Junto con description se introduce en el modelo como contexto, por lo que se recomienda el inglés. |
version | string | Sí | Versión semántica; el mercado lo utiliza para detectar actualizaciones. |
description | string | Sí | Una frase que describe lo que hace el complemento (inglés). |
author | string | No | Autor. |
readme | string | No | La descripción detallada que se muestra en la página de detalles del mercado admite Markdown. Las imágenes que contiene deben ser https URL; no se admiten rutas relativas a archivos empaquetados en el zip. |
icon | string | No | Icono que se muestra en la lista del mercado y en la página de detalles: una ruta relativa a un archivo incluido en el zip (por ejemplo, icon.png). Debe ser PNG, no SVG, al menos 128×128. |
main | string | Sí | Script de entrada, relativo a la carpeta del complemento. .. no se permite escapar de la carpeta. |
permissions | string[] | Sí | network / filesystem / notifications; puede ser una matriz vacía. Consulte "Modelo de permisos". |
tools | object[] | Sí | Declaraciones de herramientas; puede ser una matriz vacía. Consulte "Herramientas y protocolo de llamadas". |
documentParsers | object[] | No | Capacidad de análisis de archivos. |
ui | object | No | Panel flotante:{ entry, title } |
views | object[] | No | Vistas acopladas:{ id, title, icon, entry, width? } |
sessionAction | object | No | Ícono de la barra de herramientas, como máximo uno por complemento. |
configuration | object[] | No | Lista de entradas de configuración. |
commands | object[] | No | Entradas de la paleta de comandos. |
keybindings | object[] | No | Atajos. command debe hacer referencia al tool de una entrada en commands[]; de lo contrario, se rechaza la instalación. |
menus | object | No | Por ahora solo está disponible la ubicación session/context. |
activationEvents | string[] | No | Sólo onStartupFinished por ahora. |
Convenciones de idioma para texto
El texto del manifiesto tiene dos audiencias. Para el modelo: name, description, tools[].description, tools[].parameters.*.description. Escríbalos en inglés; Los modelos entienden las descripciones de herramientas en inglés y completan los parámetros de manera más confiable. Para personas: tools[].summary (resumen de una línea en la página de consentimiento), ui.title, views[].title, sessionAction.tooltip, configuration[].label, commands[].title y title dentro de menus. Escríbalos en el idioma de sus usuarios objetivo.
04Modelo de permiso
permissions debe reflejar honestamente lo que realmente hace el código. La página de consentimiento de preinstalación enumera cada uno para que los usuarios puedan decidir si realizar la instalación; La revisión del mercado también verifica la declaración con el código.
| Permiso | Cuando se debe declarar | Cómo lo trata el anfitrión |
|---|---|---|
filesystem | Leer o escribir archivos de usuario (leer código de proyecto, generar documentos, almacenar datos en la carpeta de inicio) | Consentimiento informado, mostrado al usuario. |
network | Realizar cualquier solicitud de red (API de terceros, descargas) | Consentimiento informado, mostrado al usuario. |
notifications | Mostrar notificaciones del sistema a través del show_notification RPC inverso | Enforced: llamarlo sin la declaración devuelve host_error y no se muestra ninguna notificación. |
filesystem y network son actualmente declaraciones de nivel de consentimiento, no un entorno limitado de ejecución: el host no intercepta fs o fetch. Precisamente por eso las declaraciones deben ser honestas. Los complementos que no declaran lo suficiente se rechazan en la revisión del mercado y pierden la confianza del usuario cuando se descubren. Tampoco declare demasiado (los permisos no utilizados hacen que los usuarios duden).Privacidad y datos
context.cwd es la carpeta del proyecto del usuario y puede contener código fuente y configuración confidencial; Los argumentos de la herramienta pueden contener la conversación del usuario. No envíe estos datos a través de la red a menos que la función lo requiera, y cuando lo haga, indique en description y summary qué se envía y a quién. Mantenga los datos persistentes del complemento en un archivo en la carpeta de inicio del usuario con el nombre de la identificación del complemento, para que sea fácil de encontrar al desinstalarlo.
05Herramientas y protocolo de llamadas
Declaración
| Campo | Descripción |
|---|---|
name | Nombre de la herramienta en letras minúsculas y guiones bajos, único en toda la aplicación (está registrado con el modelo junto con las herramientas integradas y las herramientas de otros complementos). |
description | Descripción del modelo (inglés). Indique tres cosas: qué hace la herramienta, qué dice el usuario, cuándo se debe llamar y cuándo no se debe llamar. Este es el campo más importante para determinar si la IA utiliza su complemento. |
summary | Resumen de una línea legible por humanos que se muestra en la página de consentimiento. Opcional pero muy recomendable; de lo contrario, se muestra una descripción truncada. |
parameters | Objeto de esquema JSON estándar con un description en cada propiedad. El modelo completa los argumentos y el host los pasa sin validación adicional, así que verifique los campos obligatorios en su código. |
renderAs | Opcional; Actualmente solo checklist: el host representa la matriz todos de los argumentos de llamada como una tarjeta de lista de verificación, consulte a continuación. |
tools[] aquí: sessionAction.tool, commands[].tool y el campo tool dentro de menus solo se verifica que sean cadenas no vacías en el momento de la instalación; el anfitrión no verifica que el nombre esté declarado en tools[] y aun así envía una llamada con ese nombre cuando se activa el botón, acceso directo o elemento de menú. Por lo tanto, una acción puramente activada por la interfaz de usuario se puede manejar completamente en tu propio index.js sin aparecer en tools[], pero entonces la IA nunca podrá verla ni llamarla. Si desea que se pueda activar la misma acción al hacer clic y que la IA actúe en una solicitud de chat, declare ese mismo nombre en tools[] también, de modo que ambos puntos de entrada compartan un controlador; si está destinado a permanecer solo en la interfaz de usuario, déjelo sin declarar; no es necesario agregar una entrada solo para que parezca completo.Protocolo de mensajes
El anfitrión envía call_tool; el complemento debe responder con un tool_result o tool_error llevando el mismo requestId. Una llamada sin respuesta dentro de los 30 segundos caduca y el modelo recibe un error.
content acepta solo los bloques text y image (imagen como base64 data más mimeType); otros tipos se eliminan. details son datos estructurados arbitrarios que nunca se introducen en el modelo; es para la representación de la interfaz de usuario del host y sus propias vistas acopladas.
Resultados del archivo: tarjetas de archivo
Representación de lista de verificación: lista de verificación renderAs
Escribir una buena descripción
Describa el desencadenante en imperativo ("Llame a esto cuando el usuario lo solicite...") y indique las exclusiones ("No llame a esto para..."). Si el resultado es un archivo, solicite al modelo que haga referencia al enlace del archivo devuelto en lugar de afirmar que se generó. Si los argumentos se reenvían a una API de generación externa, indique en qué idioma deberían estar. Evite frases ingeniosas como "administrar todos"; el modelo no sabrá cuándo utilizar la herramienta.
06Vistas acopladas (vistas)
Una vista acoplada es una página persistente en la barra lateral derecha de la sesión: aparece un ícono adicional en la barra de herramientas de la sesión y su HTML se muestra a la derecha cuando se abre. El estado de la página (posición de desplazamiento, borradores) sobrevive al cambio de sesiones y al colapso/expansión, la misma semántica que una vista de barra lateral de VS Code.
| Campo | Descripción |
|---|---|
id | Único dentro del complemento. |
title | Texto de información sobre herramientas para el icono (legible por humanos). |
icon | Elija de la lista de hosts permitidos: git-branch, checklist. Mantiene los íconos consistentes en toda la aplicación; No se aceptan imágenes personalizadas. |
entry | Archivo HTML, relativo a la carpeta del complemento. |
width | Ancho del panel predeterminado opcional en píxeles, de 240 a 640, 360 predeterminado. Los usuarios pueden arrastrar para cambiar el tamaño y se recuerda el tamaño. |
Tiempo de ejecución de la página
La página se ejecuta en una zona de pruebas (sandbox + contextIsolation, sin nodo, sin acceso a los datos de la aplicación host) y solo puede comunicarse con su propio proceso de complemento a través de los pocos métodos en window.pluginHost. Trae tus propios estilos; Se recomienda seguir el esquema claro/oscuro de la aplicación como en el siguiente ejemplo.
Patrón recomendado: en la primera carga llame a una de sus propias herramientas de consulta con invoke() y haga que devuelva datos estructurados en details; luego presione cada cambio del proceso del complemento con ui_push en lugar de sondear. Cuando la IA cambia los datos de la conversación, el panel se actualiza inmediatamente.
07Panel flotante (ui)
ui: { entry, title } declara una ventana flotante independiente (900×700) que los usuarios abren desde el menú "⋯" en la lista de complementos; se destruye al cerrar. El entorno de la página y la API window.pluginHost son idénticos a las vistas acopladas, y ui_push se entrega tanto al panel flotante como a las vistas acopladas. Adecuado para grandes paneles abiertos ocasionalmente; use views para el contenido que debe permanecer al lado de la sesión.
08Icono de la barra de herramientas de sesión (sessionAction)
Como máximo un icono persistente por complemento. Al hacer clic en él, se llama tool con argumentos vacíos, por lo que esa herramienta debe hacer algo significativo sin parámetros.
| Campo | Descripción |
|---|---|
tool | Herramienta para llamar al hacer clic. |
icon | Nombre del icono incluido en la lista de permitidos. |
tooltip | Coloca el cursor sobre el texto. |
visibleTool | Opcional. Cuando se establece, se llama con argumentos vacíos antes de renderizar y el booleano details.visible en el resultado decide si se muestra el icono. Útil para comprobaciones en tiempo de ejecución como "¿la carpeta actual es un repositorio git?". |
09Ajustes (configuración)
Las entradas declaradas aparecen en la configuración del complemento en la página de configuración. El host almacena los valores modificados por el usuario y los pasa como context.config en cada call_tool (tecleado por id, volviendo a defaultValue), ya sea que la llamada provenga de la IA, el ícono de la barra de herramientas o su panel. Nunca necesitas pedirlos.
| type | Representado como | tipo de valor predeterminado |
|---|---|---|
select | Lista de opción única; las opciones vienen de optionsTool | string |
boolean | interruptor de palanca | boolean |
string | Entrada de texto, comprometida en desenfoque | string |
number | Entrada de números | number |
10Paleta de comandos/atajos/menú contextual
Los tres son puntos de entrada diferentes para "llamar a una herramienta con argumentos vacíos"; un complemento puede declarar varios.
| Campo | Forma | Descripción |
|---|---|---|
commands | { tool, icon, title }[] | Se muestra en la paleta de comandos Ctrl/Cmd+K y se activa después de que el usuario lo busca. |
keybindings | { command, key }[] | command debe ser igual al tool de una entrada en commands[]. key usa la notación mod+shift+g, donde mod es Cmd en macOS y Ctrl en otros lugares. Los conflictos con otros atajos no se verifican estáticamente, así que elija combinaciones poco comunes. |
menus | { "session/context": { tool, icon, title }[] } | Agregado al menú en una fila de sesión. Sólo esta ubicación está disponible por ahora. |
11Analizadores de documentos (documentParsers)
Cuando el usuario coloca un archivo en el cuadro de entrada, el host busca analizadores declarados por complementos habilitados por tipo MIME y pasa el contenido del archivo como base64 al toolName correspondiente. Esta no es una herramienta a la que la IA decida llamar, así que no también incluya la herramienta de análisis en tools, o quedará expuesta como una herramienta a la que la IA puede llamar.
12RPC inverso (host_request)
El proceso del complemento no tiene API de Electron. Cuando necesita una capacidad real del sistema, envía host_request al host, que responde con host_response o host_error. Este canal es totalmente independiente de call_tool; puede usarlo mientras maneja una llamada de herramienta o desde un temporizador.
| capability | params | result | Condición previa |
|---|---|---|---|
show_notification | { title, body?, viewId? } | { shown: true } / { shown: false, reason: "disabled" | "unsupported" } | Requiere el permiso notifications. Devuelve deshabilitado en lugar de un error cuando el usuario desactivó las notificaciones de escritorio en la configuración. Cuando viewId apunta a una de sus vistas acopladas, al hacer clic en la notificación, la aplicación pasa al frente y expande esa vista. |
render_pdf | { outputPath, title, content } | {} | el contenido es Markdown; el host procesa un PDF en OutputPath con su procesador incorporado. |
13Ciclo vital
| Escenario | Comportamiento |
|---|---|
| Comenzar | Perezoso por defecto: no se inicia con la aplicación, se bifurca en la primera llamada a una de sus herramientas (IA, ícono de la barra de herramientas, panel, comando, análisis de documentos). Los complementos que declaran activationEvents: ["onStartupFinished"] se inician inmediatamente después de que la aplicación termina de iniciarse; Úselo solo para complementos que necesiten temporizadores en segundo plano (recordatorios, sondeos), no para complementos de herramientas comunes. |
| Residente | Una vez iniciado, el proceso permanece activo y se reutiliza en todas las llamadas a herramientas. Puede almacenar en caché el estado en la memoria, pero asume que puede reiniciarse en cualquier momento. |
| Chocar | Si el proceso sale inesperadamente, el host lo reinicia: inmediatamente, luego después de 5 y 15 segundos. Después de 3 fallos consecutivos, se marca como "fallado" y ya no se vuelve a intentar; los usuarios ven el estado en la página del complemento. Llamadas en vuelo todos los errores de devolución. |
| Desactivar/desinstalar/reinstalar | Se da por terminado el proceso y se destruyen las vistas acopladas y los paneles flotantes; una reinstalación reemplaza toda la carpeta. |
| Registros | Su stdout/stderr se escribe en el archivo de registro de la aplicación con el prefijo ID del complemento. Simple console.log es suficiente para depurar; consulte "Depuración y preguntas frecuentes". |
ELECTRON_RUN_AS_NODE=1, cwd es la carpeta de instalación del complemento y la versión de Node coincide con la de Electron incluida con la aplicación. No dependa de ningún paquete instalado globalmente y no asuma que npx existe.14Embalaje y publicación
Embalaje
Comprima la carpeta del complemento con manifest.json en la raíz del archivo. Si tiene dependencias de terceros, agrúpelas primero en un solo archivo con esbuild/webpack en lugar de enviar el node_modules completo.
Publicar en el mercado
AnBoWork → Herramientas → Complementos → pestaña "Mercado" → "Publicar complemento" en la esquina superior derecha, luego sube el archivo zip. Los envíos ingresan a revisión, que verifica que la declaración del manifiesto coincida con el código (especialmente los permisos). Una vez aprobado, otros usuarios pueden encontrarlo e instalarlo en el mercado, y la IA puede instalar complementos verificados para los usuarios automáticamente cuando lo considere necesario.
Actualizaciones
Suba version y publique nuevamente. La aplicación compara la versión instalada con la versión del mercado y solicita una actualización; la reinstalación mantiene el estado habilitado del usuario y los valores de configuración.
15Ejemplo completo: Cuadrante Todo
Un complemento real y funcional (recortado): la IA puede agregar y eliminar todos, la barra lateral derecha muestra un tablero que se actualiza en tiempo real y puede enviar recordatorios de notificaciones del sistema. Encadenar estos tres cubre el protocolo de la herramienta, los push de vista acoplada y el RPC inverso.
16Depuración y preguntas frecuentes
| Síntoma | Causa y solución |
|---|---|
| La validación del manifiesto falla durante la instalación | Verifique cada campo con la tabla "Campos de manifiesto", ya que el mensaje indica: formato de identificación, principal/entrada no debe contener .., el icono debe estar en la lista de permitidos, el comando de combinaciones de teclas debe apuntar a una herramienta existente en los comandos, ancho entre 240 y 640. |
| La IA nunca llama a mi herramienta | Casi siempre es un problema description: el disparador no está claro o no está escrito en inglés. Consulte "Escribir una buena descripción". También verifique que el nombre de la herramienta no colisione con otra herramienta. |
| Tiempo de espera de llamada (30 s) | El script de entrada no respondió con tool_result. Por lo general, requestId no se repite, el mensaje type está mal escrito o el script se inicia al iniciar y sale. Busque líneas con el prefijo [plugin:your-id] en el registro de la aplicación. |
| El estado del complemento muestra "fallado" | 3 salidas fallidas consecutivas. Comúnmente un require de un paquete faltante; ejecutar node index.js en la carpeta del complemento lo reproduce. Después de solucionarlo, desactive y vuelva a activar el complemento en la página del complemento. |
| El panel se abre en blanco | Ruta entry incorrecta o un error JS en la página. La página se ejecuta en una zona de pruebas sin require de Node; solo window.pluginHost está disponible. |
| No aparece la notificacion | Verifique en orden: el manifiesto declara notifications; el resultado no es shown:false (el usuario desactivó las notificaciones del escritorio); el sistema operativo permite notificaciones desde AnBoWork. |
| Los valores de configuración no son legibles | Los valores están en message.context.config[id], no en params. |
Ubicación del archivo de registro
| SO | Camino |
|---|---|
| macOS | ~/Library/Logs/AnBoWork/main.log |
| Windows | %USERPROFILE%\AppData\Roaming\AnBoWork\logs\main.log |