Saltar al contenido
CADCAMFUN
Documentos

Documentación

Complementos

Manifiestos de extensión, API de host de trabajo, herramientas asistentes y el contrato de instalación del complemento del navegador por separado.

Traducido automáticamente del inglés. Ver el original en inglés

Elija la superficie de extensión

@cadcamfun/plugin-sdk define el contrato de complemento de trabajador con un plugin.json manifiesto y versión API 1. Su host expone servicios controlados por capacidad y ejecuta funciones de complemento en los trabajadores de Bun. El cargador del asistente de producción actualmente acepta complementos que solo solicitan ai:tool.

El /api/plugins La familia HTTP utiliza un contrato de complemento de navegador diferente: paquetes ZIP con manifest.json, a main entrada, permisos del navegador, configuración y arranque de JavaScript. La instalación de un paquete a través de esa API no lo convierte en un complemento del SDK de trabajo. Utilice el manifiesto y el ciclo de vida que coincidan con la integración prevista.

Manifiesto del SDK del trabajador

plugin.json para una extensión de asistente
{
  "id": "com.example.shop-helper",
  "name": "Shop helper",
  "version": "1.0.0",
  "apiVersion": "1",
  "entry": "index.js",
  "capabilities": ["ai:tool"],
  "contributes": {
    "aiTools": [{
      "id": "lookup",
      "description": "Look up the shop's documented inspection checklist.",
      "kind": "read",
      "parameters": { "type": "object", "properties": {} },
      "entry": "lookup"
    }]
  }
}

Los identificadores utilizan una forma de DNS inverso, la versión es semántica major.minor.patch con una presentación preliminar opcional, y apiVersion debe ser "1". Las rutas de entrada son relativas al directorio del complemento. Las contribuciones pueden declarar comandos, paneles, postprocesadores, operaciones y herramientas auxiliares; declarar una contribución no conecta esa característica a cada host.

El esquema permite opciones opcionales. signature y dev campos. El host de trabajo actual registra estos valores pero no realiza la verificación de firma criptográfica durante la instalación. Un campo de firma por sí solo no es evidencia de un editor verificado.

Entrada de módulo y funciones de IA

definePlugin es un asistente de identidad escrito para un módulo con un manifiesto y activate(ctx). La activación puede devolver una función de limpieza y el módulo puede exponer deactivate. El SDK describe estos enlaces del ciclo de vida; su disponibilidad depende del arranque del trabajador concreto, como se detalla a continuación.

Las funciones del asistente se exportan a través de un aiTools registro; la contribución entry nombra la función en ese registro. Una contribución de herramienta incluye su descripción, esquema de parámetros JSON y read o write amable. Una herramienta de escritura se dirige a través de una solicitud de aprobación humana en el asistente integrado; un puente externo solo recibe herramientas de complemento de lectura permitidas.

Agrupe la entrada del trabajador como un módulo autónomo. El host trabajador lee el origen de entrada y lo importa a través de un módulo blob. Trate las importaciones relativas de paquetes o archivos como una preocupación de integración separada en lugar de asumir un cargador de sistema de archivos estilo Nodo.

API controladas por capacidad

El SDK reconoce drawing:read, drawing:write, toolpath:read, storage, ui:panel, y ai:tool. Dibujar escribir implica dibujar leer. El host general obtiene capacidades efectivas del manifiesto instalado y las verifica en RPC; la aplicación de incrustación decide qué manifiestos y superficies está dispuesta a cargar.

El contexto del SDK puede exponer lecturas de dibujos y agregar/actualizar/eliminar parches de entidades, lecturas de rutas de herramientas/programas, almacenamiento de valores-clave de cadenas privadas y registro declarativo de comandos/paneles. Los servicios faltantes están ausentes del contexto. Uso de claves de almacenamiento plugin:<id>: espacios de nombres y rechazar claves absolutas o transversales principales.

El cargador asistente de producción solo admite ai:tool. Un manifiesto que solicita capacidades de dibujo, trayectoria de herramienta, almacenamiento o interfaz de usuario se omite con una advertencia. No otorga silenciosamente esas superficies ni carga sus capacidades más amplias en el host asistente.

Carga y ciclo de vida del trabajador.

Para habilitar una extensión del asistente, coloque su plugin.json y entrada incluida bajo <dataDir>/plugins/<id>/ y enumerar el identificador en <dataDir>/plugins/enabled.json, una matriz JSON. El identificador de la carpeta debe coincidir con el manifiesto. La carga se produce mientras se crea el servicio del complemento asistente; un complemento fallido registra una advertencia sin detener la aplicación.

El host general admite estados instalado, habilitado, deshabilitado y con fallas, con operaciones de instalación, habilitación, deshabilitación, desinstalación, llamada de comando, llamada a herramienta AI y configuración. Enable crea un trabajador y completa su protocolo de enlace de arranque; desactivarlo lo derriba. La desinstalación elimina el estado del registro y el espacio de nombres de almacenamiento a través de las dependencias inyectadas del host.

Los trabajadores comienzan con un entorno vacío y el arranque elimina las API globales seleccionadas. Esta es una restricción a nivel de aplicación, no una zona de pruebas del sistema operativo: los globales de Bun siguen siendo accesibles. Habilite solo el código de extensión que sea apropiado para ejecutarse dentro de los límites del proceso de la aplicación.

Límites de tiempo de ejecución

El host define una configuración de memoria de trabajo de 256 MB, un límite de tarifa de 2,000 llamadas por minuto y, como máximo, 64 llamadas pendientes por complemento. El comportamiento del tiempo de espera del comando lo proporciona el host de incorporación; el asistente de carga usa 10 segundos. Las llamadas a herramientas de IA tienen una fecha límite separada de 30 segundos. Los tiempos de espera, la ausencia de herramientas, las fallas de los trabajadores, las fallas de capacidad y el agotamiento de la cola devuelven fallas del host escritas o resultados de herramientas legibles.

El seguimiento de fallas falla en un complemento después de tres fallas en diez minutos. Estos controles de host vinculaban el RPC cooperativo y el comportamiento del ciclo de vida; La configuración de memoria pasada a Bun no sustituye a un ejecutable aislado por separado.

Los límites están definidos en apps/sidecar/src/plugins/host.ts: CALL_TIMEOUT_MS (5,000 ms por llamada ordinaria), AI_TOOL_TIMEOUT_MS (30,000 ms por llamada a la herramienta asistente), MEMORY_LIMIT_MB (256), CALL_RATE_LIMIT (2,000 llamadas por complemento por minuto), MAX_PENDING_CALLS (64), y CRASH_LIMIT (3 falla en un 10 minuto CRASH_WINDOW_MS, después de lo cual el complemento se desactiva automáticamente).

API de instalación ZIP y complemento del navegador

POST /api/plugins/install acepta un archivo de varias partes. El instalador lee manifest.json desde la raíz ZIP o un único directorio de nivel superior, valida el manifiesto del complemento del navegador y almacena sus archivos en <dataDir>/storage/plugins/<id>/. Uso de manifiestos del navegador main, engines.cadcamy una lista de permisos del navegador, en lugar de SDK entry, apiVersiony capacidades.

GET /api/plugins enumera esas entradas instaladas; detallar, habilitar/deshabilitar, desinstalar, actualizar y configurar los puntos finales operan en su registro. /api/plugins/bootstrap.js?id=… sirve JavaScript; /api/plugins/serve?id=…&file=… sirve archivos de complemento. Estas son operaciones de texto/binarias con sus tipos de contenido declarados.

El navegador de registro local lee los metadatos del paquete en <dataDir>/plugins-registry. Es un catálogo de manifiesto local. La instalación del archivo, el listado del registro y la carga de la extensión del asistente de trabajo son operaciones independientes.

Ayudantes del SDK

effectiveCapabilities, hasCapability, y missingCapabilities inspección de capacidad de soporte. requireCapability genera un error de capacidad cuando una superficie de contexto solicitada está ausente. storageNamespace y storageKey construir claves con espacios de nombres; parseManifest valida JSON; manifestKey formatea un par ID/versión.

Puntos de entrada de implementación

packages/plugin-sdk/src posee las API públicas de manifiesto, capacidad, contexto, complemento y host de prueba. apps/sidecar/src/plugins/host.ts posee el ciclo de vida del trabajador y RPC; services/ai-plugins.ts posee la carga del archivo de consentimiento y el registro del asistente. La instalación del navegador se implementa en http/plugins.ts y repos/plugin-registry-repo.ts.

Revisión de extensión

Mantenga los esquemas de contribución precisos, devuelva pequeños resultados estructurados y declare el comportamiento de lectura/escritura de manera honesta. Pruebe con el host de inserción real: la disponibilidad del SDK no establece acceso de producción a los registros de dibujo, almacenamiento, interfaz de usuario o publicaciones. El complemento nikcli independiente es un cliente de acción HTTP y tiene un propósito diferente al del código cargado en un trabajador.

Complete el módulo asistente de muestra

El plugin.json ejemplo arriba de nombres aiTools.lookup. Este es el correspondiente autocontenido. index.js. El código del módulo de nivel superior se ejecuta cuando se importa; la función de búsqueda declarada se ejecuta cuando se llama.

index.js
export const aiTools = {
  lookup: async () => ({
    ok: true,
    checklist: [
      "Compare the drawing revision with the job traveller.",
      "Record the measuring instrument and its calibration status.",
      "Record each inspected dimension and the measured value."
    ]
  })
}

Estas son instrucciones de taller de muestra, no un estándar de inspección incorporado. Reemplácelos con el contenido que realmente posee su extensión. Para admitir este módulo en la próxima inicialización del servicio, el archivo habilitado es:

<dataDir>/plugins/enabled.json
["com.example.shop-helper"]

El catálogo en ejecución expone un identificador derivado de los ID de complementos y herramientas. Descúbrelo a través GET /api/ai/actions; no asuma que el registro ZIP del navegador es la lista habilitada del asistente. Recargar la aplicación/servicio es la forma confiable de volver a leer el archivo de consentimiento de producción; Este cargador no configura ningún observador del sistema de archivos.

Fuente: apps/sidecar/src/services/ai-plugins.ts, packages/ai/src/tools/plugin-tool.ts, y apps/sidecar/test/ai-plugin-tools.test.ts.

Esquemas de argumentos y límites del ciclo de vida.

El ID local de una herramienta debe comenzar con una letra minúscula y contener letras minúsculas, dígitos o guiones bajos, con un máximo de 40 caracteres. Las descripciones contienen 10–2,000 caracteres. La contribución debe nombrar una función de entrada que no esté vacía y un esquema de parámetros JSON. El adaptador de aplicación valida los argumentos antes de llamar al trabajador; una negativa puede devolver un estructurado ok: false resultado sin terminar el complemento.

El SDK público describe activate, limpieza y deactivate puntos de entrada. Los controladores RPC de activación/desactivación del actual trabajador Bun reconocen los mensajes del ciclo de vida pero no invocan las funciones del módulo exportado. Por lo tanto, las extensiones asistentes deberían poner su comportamiento invocable en aiTools y evite depender de las devoluciones de llamadas de activación del SDK para la configuración o limpieza.

El programa de arranque del trabajador general también contiene controladores de dibujo/trayectoria/UI de marcador de posición. No constituyen dibujos de producción ni integración de UI. La restricción del asistente de carga a ai:tool evita que estas superficies no compatibles se anuncien como acceso a aplicaciones en funcionamiento.

Fuente: packages/plugin-sdk/src/manifest.ts, plugin.ts, apps/sidecar/src/plugins/host.ts (PLUGIN_BOOTSTRAP), y services/ai-plugins.ts.

Diagnosticar una extensión faltante o defectuosa

  • No hay herramientas en el catálogo: verifique JSON habilitado válido, coincidencia exacta de ID de carpeta/manifiesto, decodificación de manifiesto y el ai:tool capacidad. Lea la advertencia de inicio de un complemento omitido.
  • Solicitudes de manifiesto superficies no compatibles: elimine las capacidades no compatibles solo si el código realmente no las necesita. Un complemento asistente no puede adquirir acceso de escritura y dibujo simplemente declarándolo.
  • NoTalHerramienta: hacer contributes.aiTools[].entry coincidir con una función exportada en aiTools. El ID de contribución y el nombre de la entrada tienen diferentes propósitos.
  • Fallo de validación del argumento: inspeccione el esquema JSON y los campos obligatorios. Los valores incorrectos se rechazan antes de la ejecución, como lo demuestran las pruebas de integración de aplicaciones y de trabajadores reales.
  • Tiempo de espera o estado de error: investigar bloqueos de trabajo, promesas no resueltas o fallas; Los fallos repetidos fallan en el complemento. Vuelva a habilitarlo solo después de corregir la causa.
  • El instalador ZIP rechaza el manifiesto: utilizar el complemento del navegador manifest.json contrato para ese punto final. Cambiar el nombre de un trabajador plugin.json no traduce sus campos.

Fuente: apps/sidecar/test/plugins-ai-tools.test.ts, ai-plugin-tools.test.ts, plugins-http.test.ts, y src/plugins/host.ts.

Referencia manifiesta

Cada complemento incluye un plugin.json. parseManifest(json) lo analiza y lo valida en un solo paso, convirtiendo un error de sintaxis JSON en el mismo canal de error que un error de esquema, por lo que una pantalla de instalación solo necesita manejar un tipo de error.

CampoRegla
idIdentificador de DNS inverso: 3–128 caracteres, letras minúsculas, dígitos y guiones en al menos dos etiquetas separadas por puntos, por ejemplo com.example.gear-generator.
nameNombre para mostrar no vacío.
versionmajor.minor.patch, seguido opcionalmente de un sufijo previo al lanzamiento, como -beta.1.
apiVersiondebe ser la cuerda "1"; es la única versión de API de complemento.
entryRuta del módulo ES relativa a la carpeta del complemento.
capabilitiesMatriz de cadenas de capacidad (ver más abajo). Todo lo que esté fuera de la lista cerrada es un error manifiesto.
contributesOpcional commands, panels, postProcessors, operations, y aiTools.
signatureFirma Ed25519 sobre el hash del archivo; requerido para instalaciones empaquetadas.
devtrue marca un complemento de desarrollo local: se omiten las comprobaciones de firmas y la interfaz de usuario muestra una insignia.
ContribuciónCampos
commands[]id, title, opcional keybinding como Mod+Shift+G.
panels[]id, title, entry: una función exportada que devuelve el árbol declarativo del panel. Nunca hay acceso DOM.
postProcessors[]id, title, entry: un exportado (program, options) => string función.
operations[]id, title, entry: un registro exportado con un parámetro schema y un puro generate(params, geometry, tool, stock) que devuelve una ruta de herramienta.
aiTools[]id pareo ^[a-z][a-z0-9_]{0,39}$, description (10–2,000 caracteres; el modelo lo lee), kind read o write, parameters (Esquema JSON de los argumentos), y entry.

Ayudantes: manifestKey(m) regresa id@version; requestedCapabilities(m) devuelve la lista de capacidades ordenadas para su visualización; isDevPlugin(m) y isSigned(m) responda las preguntas sobre la política de instalación.

Capacidades y contexto del complemento

Las capacidades son lo único mediante lo que puede actuar un complemento. El manifiesto declara lo que necesita el complemento, el usuario otorga un subconjunto y el host crea un contexto que contiene exactamente las superficies otorgadas. Cada superficie es opcional en el tipo, por lo que una capacidad faltante es visible tanto en tiempo de compilación como en tiempo de ejecución en lugar de convertirse en una operación silenciosa y no operativa.

CapacidadSuperficie de contextoPermiteImplica
drawing:readctx.drawing.read()Lea el dibujo abierto (o undefined cuando no hay ninguno abierto).—
drawing:writectx.drawing.patch(patch)Aplicar AddEntity, UpdateEntity, o RemoveEntity parches; devuelve la nueva revisión.drawing:read
toolpath:readctx.toolpath.list(), .program(id)Lea trayectorias de herramientas y programas de código G.—
storagectx.storageCadenas de valores-clave con espacios de nombres: get, set, delete, keys.—
ui:panelctx.uiregisterCommand y registerPanel (solo declarativo).—
ai:toolninguno (contribuciones manifiestas)Ofrezca herramientas al asistente y, de solo lectura, a un nikcli independiente.—
effectiveCapabilities(granted) resuelve implicaciones, por lo que un complemento que declara drawing:write no necesita declarar drawing:read. Cada contexto también tiene pluginId, el resuelto capabilities, y un log con debug, info, warn, y error; el host antepone las líneas de registro con el ID del complemento. Usar requireCapability(ctx, capability, surface) para obtener una superficie o fallar con un CapabilityError que nombra la subvención faltante.

Pruebe un complemento con el host de prueba del SDK

createTestHost construye un host en memoria con las mismas reglas de capacidad que el sidecar. Solo las capacidades concedidas aparecen en el contexto y usted puede proporcionar un dibujo, trayectorias y programas. El siguiente ejemplo está completo y se ejecuta con bun en el espacio de trabajo.
frame-plugin.test.ts
import { cad } from "@cadcamfun/core"
import { createTestHost, definePlugin, requireCapability, testManifest } from "@cadcamfun/plugin-sdk"

const manifest = testManifest({
  id: "com.example.frame",
  capabilities: ["drawing:write", "storage", "ui:panel"],
})

const plugin = definePlugin({
  manifest,
  activate(ctx) {
    const drawing = requireCapability(ctx, "drawing:write", "drawing")
    ctx.ui?.registerCommand({ id: "frame.add", title: "Add frame line" })
    ctx.storage?.set("runs", "1")
    drawing.patch({
      _tag: "AddEntity",
      entity: { ...cad.baseEntity("frame-1"), _tag: "Line",
                start: { x: 0, y: 0 }, end: { x: 100, y: 0 } },
    })                                   // returns revision 1
    return () => ctx.log.info("teardown") // runs on deactivation
  },
})

const host = createTestHost({ manifest, drawing: cad.emptyDrawing("d1", "Demo") })
const stop = await host.activate(plugin)
host.drawing()?.entities.length     // 1
host.context.storage?.get("runs")   // "1"
host.ui.commands                    // [{ id: "frame.add", title: "Add frame line" }]
await stop()

// Without the grant, requireCapability throws:
const denied = createTestHost({ manifest, granted: ["storage"] })
await denied.activate(plugin)
// CapabilityError: Plugin com.example.frame may not use "drawing:write":
// it was not granted at install time
  • testManifest(overrides) comienza desde un manifiesto mínimo válido (com.example.test-plugin, versión 1.0.0, API 1, entrada index.js, sin capacidades).
  • granted el valor predeterminado es todo lo que solicita el manifiesto. Pase una lista más pequeña para probar las rutas denegadas.
  • host.storage es una instantánea tomada cuando se crea el host. Leer valores en vivo a través de host.context.storage.
  • host.on(commandId, handler) y host.invoke(commandId, args) ejercer comandos registrados.
  • runPostProcessor ejecuta una publicación aportada contra un programa, y keyOf(pluginId, key) muestra la clave de almacenamiento con espacio de nombres para que las pruebas puedan afirmar el aislamiento.

Cómo carga la aplicación los complementos del asistente

  1. Al inicio, el sidecar lee <data dir>/plugins/enabled.json, una matriz JSON de ID de complementos. No se carga nada a menos que aparezca allí.
  2. Para cada identificación que lee <data dir>/plugins/<id>/plugin.json y lo analiza. El nombre de la carpeta debe ser igual al manifiesto. id.
  3. Solo ai:tool está conectado en este host. Un manifiesto que solicita acceso a dibujo, trayectoria, almacenamiento o interfaz de usuario se omite con una advertencia en lugar de cargarse con superficies que silenciosamente no harían nada.
  4. El complemento se instala en un host de trabajo y se habilita. Un complemento que no puede cargar registros Plugin <id> was not loaded: ... y nunca detiene el inicio de la aplicación.
  5. Cada herramienta aportada se ofrece al asistente como plugin_<slug of plugin id>_<tool id>, como máximo 80 caracteres, donde la barra escribe en minúsculas el ID y reemplaza otros caracteres con guiones bajos. com.example.bolt-circle con herramienta bolt_circle se convierte plugin_com_example_bolt_circle_bolt_circle.
  6. Los argumentos se validan con el esquema JSON de la herramienta antes de que el trabajador los vea. Si el esquema excede los 20,000 caracteres, no es un esquema de objeto o no se puede convertir, el host acepta cualquier objeto y el complemento debe validarlo.
  7. Se devuelve una llamada que se produce, se agota el tiempo de espera o descubre que el complemento ya no existe. { ok: false, error } (texto de error de hasta 500 caracteres) al asistente en lugar de bloquear el giro. A write la herramienta se confirma con la persona antes de cada llamada, independientemente de lo que digan sus argumentos.

No es un entorno limitado de sistema operativo

El trabajador no tiene ningún proceso, recuperación o identificador de archivo propio, pero los globales de Bun siguen siendo accesibles dentro de él. Habilite solo complementos en cuyo código confíe y mantenga las herramientas de escritura al mínimo.

Reglas de identificador y versión, probadas

Valor¿Válido?Regla
com.example.gear-generatorsíDNS inverso: segmentos minúsculos de letras, dígitos y -, al menos dos 3–128 caracteres
a.bsíDos segmentos de una letra son suficientes
gearnoNecesita al menos un punto
Com.Example.xnoNo se permiten mayúsculas
com.example_x.ynoEl guión bajo no está permitido
Versión¿Válido?
1.0.0sí
1.2.3-beta.1sí
1.0no: se requieren tres números
v1.0.0no: sin prefijo
apiVersion debe ser la cuerda "1", el único complemento API importante que existe. Los ID de las herramientas de IA deben coincidir ^[a-z][a-z0-9_]{0,39}$ y se muestran al asistente como plugin_<plugin>_<id>; las descripciones deben tener 10–2,000 caracteres porque el modelo las lee.

Tipos de contribución

LlaveCamposObjetivo
commandsid, title, opcional keybinding (e.g. Mod+Shift+G)Comandos en la paleta
panelsid, title, entryUn panel representado a partir de un árbol declarativo que devuelve la función nombrada; sin acceso DOM
postProcessorsid, title, entryA (program, options) => string publicación registrada en tiempo de ejecución
operationsid, title, entryun exportado { schema, generate } registro
aiToolsid, description, kind leer|escribir, parameters (Esquema JSON), entryHerramientas ofrecidas al asistente; una herramienta de escritura se confirma antes de cada llamada

Otros campos de manifiesto: signature (Ed25519 sobre el hash del archivo, requerido para instalaciones empaquetadas) y dev (complemento de desarrollo local: omite las comprobaciones de firmas y muestra una insignia).

Resolución de capacidad, probada

Implicaciones, subvenciones faltantes, claves de almacenamiento
import { effectiveCapabilities, missingCapabilities, storageKey, requireCapability } from "@cadcamfun/plugin-sdk"

effectiveCapabilities(["drawing:write", "storage"])
// ["drawing:read", "drawing:write", "storage"]   (write implies read; sorted)

missingCapabilities(["drawing:read", "toolpath:read", "ai:tool"], ["drawing:write"])
// ["toolpath:read", "ai:tool"]

storageKey("com.example.gear", "presets/m2")   // "plugin:com.example.gear:presets/m2"
storageKey("com.example.gear", "../x")
// RangeError: storage key "../x" may not escape the plugin namespace   (same for "/abs")

requireCapability(ctxWithoutDrawing, "drawing:read", "drawing")
// CapabilityError (_tag "CapabilityDenied"):
// Plugin com.example.gear may not use "drawing:read": it was not granted at install time
Superficie en el contextoPresente cuando se concedeMétodos
drawingdrawing:read o drawing:writeread() → dibujo o undefined; patch(p) → nueva revisión, con AddEntity, UpdateEntity, RemoveEntity parches
toolpathtoolpath:readlist(), program(toolpathId)
storagestorageget, set, delete, keys; valores de cadena
uiui:panelregisterCommand, registerPanel
logsiempredebug, info, warn, error

En 3D

Paquetes de complementos en el espacio de trabajo Arrastrar para orbitar · desplazarse para hacer zoom · arrastrar con el botón derecho para desplazarse
All 13 workspace packages from their package.json files; each line is a workspace:* dependency (17 in total). Rows are dependency depth: packages with no workspace dependencies at the front, the sidecar, which depends on 8 of them, at the back. Orange boxes are apps. Highlighted: plugin-sdk (depends on core) and the nikcli plugin, both loaded by the sidecar.