Comal/aprende

Extender Comal

Operaciones, scopes y ciclo de vida de plugins locales.

Comal 0.1.0 · Revisado el 15 oct 2026
En esta página

Un plugin añade operaciones y servicios al runtime de Comal. La casa mantiene actor, permisos, contratos y recibos: el plugin no puede autorizarse a sí mismo.

Descubrir y cargar

node bin/comal.mjs --demo --plugin-config examples/comal-plugins.json -p /plugins

Descubrir el JSON no importa el módulo. Para cargar plugins habilitados al iniciar, usa --trust-plugins. Los entrypoints son archivos locales .mjs/.js; las rutas se resuelven respecto del archivo de configuración.

{
  "plugins": [
    { "id": "hello", "module": "./hello.mjs", "enabled": true, "config": {} }
  ]
}

Una operación pequeña

export default {
  id: 'hello',
  version: '1.0.0',
  requires: [],
  provides: [],
  activate(ctx) {
    ctx.operation({
      name: 'Hello',
      description: 'Devuelve un saludo',
      input_schema: { type: 'object', additionalProperties: false },
      run() { return { message: 'Hola desde Comal' }; }
    });
  }
};

La operación se publica como plugin__hello__Hello. Cargar el módulo no concede permiso para llamarla; la invocación pasa por el juez.

Ciclo de vida

/plugins
/plugins enable hello
/plugins reload hello
/plugins disable hello

Los comandos pertenecen al usuario y los cambios mutables esperan en cola. Enable/disable/reload afectan esta sesión; para persistir selección entre procesos, edita enabled en la configuración.

La preparación de una nueva generación ocurre antes de publicarla. Un fallo de preparación conserva la anterior; la retirada cancela cooperativamente y espera operaciones iniciadas antes del cleanup. No hay rollback de efectos externos de activate.

Contratos de extensión

ctx.service consume servicios declarados en requires; ctx.provide publica los de provides. ctx.guard puede vetar operaciones propias, pero nunca superar una denegación. Los observers reciben copias inmutables; no fabrican recibos. ctx.defer registra limpieza.

Los módulos Node son código confiado del proceso, no un sandbox. Para implementaciones en otros lenguajes, expón capacidades mediante MCP o procesos autorizados. La API de plugins de Comal es propia; no promete cargar directamente paquetes de DeepSeek/Cordis.

Casos que ya existen

web publica WebSearch/WebFetch para investigar fuentes reales. delegation publica Agent/AgentBatch para separar exploraciones; no se registra en demo. El ejemplo local hello publica Hello, un comando humano Inspect y un servicio hello.greeter. Su saludo se ha ejecutado mediante CLI sin llamada al modelo.

Un plugin también puede proporcionar servicios a otro mediante requires/provides. Casos como diagnósticos de un monorepo, políticas de proyecto o adaptadores de compilación son extensiones posibles: no vienen implementadas por el ejemplo Hello.

F6 permite inspeccionar operaciones publicadas; /plugins run completa el ID y después el nombre de operación. Preparar texto no importa código ni ejecuta el handler.

Chrome Extension Lab con Codex

Para abrir Comal con el plugin chrome-lab y tu login Codex ya autenticado, usa desde el repositorio:

npm run lab:chrome -- --auth-provider codex --name residente

Para reanudar una sesión con ese plugin:

npm run lab:chrome -- --auth-provider codex --name residente --resume UUID

El launcher selecciona examples/comal-chrome-lab.json, carga el plugin y autoriza sus 15 operaciones de laboratorio. Las denegaciones explícitas prevalecen y los permisos de ediciones locales/Bash siguen separados. Conserva también tus argumentos de perfil/proveedores si los utilizas.

Comprueba /plugins: debe mostrar chrome-lab en estado active. /plugins run chrome-lab Status {} verifica la conexión sin llamar al modelo. La conexión SSH se abre cuando se invoca la primera operación, no al listar el plugin.

Si sólo aparecen web y delegation, la configuración local del laboratorio no se cargó. node bin/comal.mjs utiliza el archivo plugins.json del directorio de estado, que puede no existir; ejecutar o desarrollar el plugin no lo registra automáticamente allí. El launcher lab:chrome carga la configuración explícita en cada inicio.

lab:chrome-cycle y lab:chrome-cycle-live ejecutan experimentos y terminan. Para trabajar en la TUI con el plugin utiliza lab:chrome.

Tarea Chrome coordinada por la casa

npm run lab:chrome -- --chrome-task mi-tarea.json --name residente

El JSON declara project, directory, popup, selector y equals. Por ejemplo: {"project":"mi-extension","directory":"extension","popup":"popup.html","selector":"#status","equals":"Lista lista"}. directory debe estar dentro del workspace y contener la extensión MV3. Opcionalmente tests declara una secuencia de fill, click, reload y assert (con selector y equals o count). Esas interacciones escriben datos de prueba en la extensión; usa un proyecto propio de laboratorio.

La casa conserva el encargo, deriva las versiones y el target y verifica el cierre mediante sus operaciones normales. El modelo recibe Read/Edit/Write y acciones ChromePublish/ChromeVerify/ChromeFinish/ChromeRecover; con pruebas de interacción también ChromeTest. La configuración no concede permisos adicionales. La TUI muestra chrome:PROYECTO junto a los indicadores del modelo.

Reanuda con npm run lab:chrome -- --resume UUID; el JSON original puede faltar porque la declaración está en el stream. Otro criterio requiere otra sesión. Un despliegue incierto no se repite automáticamente. delivery.status=verified acredita sólo el criterio y pruebas declarados observados; la gobernanza y los recibos permanecen locales, sin firma externa.

Recuperar una publicación interrumpida

Después de reanudar el mismo UUID, ejecuta /work recover. La casa reconecta y compara el intento guardado, los hashes de los archivos remotos y la extensión cargada. No llama al modelo ni repite Deploy. Si devuelve recovered, /work resume permite continuar: ChromePublish abre el popup pendiente sin publicar otra vez. ChromeRecover también está disponible al residente.

Un recibo ausente, otro intento, una publicación en curso o un snapshot distinto mantienen el bloqueo. Las aperturas inciertas requieren un popup propio único ya observado; los clicks/fills inciertos y los intentos legacy sin identidad no se reconcilian automáticamente. Deployment es la observación de lectura del plugin que sustenta este control.

¿Completaste la práctica?

Marca tu lectura para seguir el recorrido.

← Volver a Dale herramientas al trabajo · ver autoevaluación
Ver esta página como Markdown

Fuente editable de esta guía: plugins.md. Las páginas de referencia se regeneran desde el inventario auditado.

Escribe para encontrar una guía o un comando.

↑ ↓ navegar · Enter abrirBúsqueda local
Explora Comal