Empaquetado e instalación¶
Un plugin de Python es una carpeta con un plugin.json y un módulo de Python.
Puedes instalar uno de dos formas: empaquetarlo como un archivo .mteplugin y
usar el instalador del editor (recomendado), o dejar la carpeta a mano en un
directorio de plugins.
Empieza por la plantilla
En el repositorio hay un punto de partida listo para copiar en
Python/templates/plugin-template-python/: tres archivos
(plugin.json, main.py, README.md) más un CLAUDE.md orientado a
Claude. Renombra la carpeta con el nombre corto de tu plugin, edita cuatro
campos de plugin.json y empieza a escribir register(ctx). El SDK
instalado incluye la misma plantilla en
share/MTEPluginSDK/plugin-template-python/.
Disposición de la carpeta del plugin¶
Todo lo que el plugin necesita debe estar dentro de esta carpeta. Las
subimportaciones funcionan, pero deben ser planas: los nombres de module con
puntos en plugin.json son una extensión futura.
Puedes añadir archivos adicionales (README, LICENSE): el anfitrión ignora lo que no reconoce.
Paquetes .mteplugin (recomendado)¶
Comprime los archivos del plugin y dale al archivo comprimido la extensión
.mteplugin (un .zip sin más también funciona). Se aceptan ambas formas:
hello.mteplugin hello.mteplugin
├── plugin.json └── hello-1.0.0/ # any folder name
└── main.py ├── plugin.json
└── main.py
La carpeta envolvente única —el resultado natural de comprimir una carpeta— se
normaliza y desaparece: el plugin se instala siempre en <Plugins>/<id>/,
identificado por el id del manifiesto, nunca por el nombre de carpeta del
archivo comprimido. Por eso también instalar la versión 2 de un plugin sustituye a
la versión 1 en lugar de ponerse a su lado.
Instálalo mediante Preferencias → Complementos → Instalar un complemento... y reinicia el editor.
Instala solo paquetes en los que confíes
El instalador comprueba que un paquete sea estructuralmente correcto (ver
más abajo); eso no hace que sea seguro ejecutar un plugin en el que no
confías. Una vez cargado, un plugin se ejecuta con el mismo acceso a tus
archivos, ajustes y red que el editor, y no está aislado. El sondeo
estático de register(...) no ejecuta ningún código en el momento de la
instalación, pero el código del plugin sí se ejecuta en el siguiente
arranque. Trata un .mteplugin (y cualquier archivo de configuración o JSON
que distribuya) como un programa desconocido: instálalo solo desde una fuente
en la que confíes. Consulta Plugins para la
advertencia completa.
Qué valida el instalador¶
El paquete se valida por completo contra una copia desechable antes de tocar nada en el disco: un paquete defectuoso nunca puede perturbar una instalación existente.
plugin.jsonse analiza correctamente, tiene unid, suapiVersioncoincide con la del editor,entryes"python"ymoduleestá presente.- El listado del archivo comprimido es seguro: sin rutas de entrada absolutas ni
con
.., como mucho 10 000 entradas, como mucho 256 MiB descomprimidos y al menos un archivo.py. - Tras extraerlo a un directorio temporal, el
<module>.pydeclarado existe y declara undef register(...)de nivel superior, el mismo sondeo estático que usa la detección. No se ejecuta ningún código de Python en el momento de la instalación.
Cualquier fallo produce un diálogo de error legible y deja intactos los plugins del editor.
Actualizar y desinstalar¶
- Instalar un paquete cuyo
idya está instalado lo sustituye. Si ese plugin está cargado en ese momento, la actualización se prepara y se aplica en el siguiente arranque. - Desinstala desde la misma página de Preferencias; la eliminación también ocurre en el siguiente arranque, cuando no hay nada cargado.
- Los plugins incluidos (integrados) no se pueden anular con un paquete instalado
que tenga el mismo
id.
Instalación a mano (dejar la carpeta)¶
El editor detecta plugins en dos directorios en cada arranque:
- Incluidos — junto al ejecutable, en
<exe-dir>/Plugins/. Aquí viven los plugins integrados (p. ej.HelloPython). - Usuario — por usuario, con permiso de escritura. En Windows es
%LOCALAPPDATA%/MTE/Plugins/, en macOS~/Library/Application Support/MTE/Plugins/y en Linux~/.local/share/MTE/Plugins/.
Se examinan ambos directorios. Si el mismo id aparece en los dos, gana la
primera aparición (los incluidos tienen precedencia). Reinicia el editor para que
recoja las carpetas nuevas: la recarga en caliente no está admitida.
Dos disposiciones aceptables¶
El examen busca plugin.json bien directamente en el directorio de plugins
(suelto), bien dentro de un nivel de subdirectorio inmediato (carpeta por plugin):
Plugins/
├── plugin.json # loose -- one plugin at the top level
├── main.py
└── hello/ # per-plugin folder -- one plugin
├── plugin.json
└── main.py
La carpeta por plugin es la disposición recomendada; es la forma que produce el instalador.
Dependencias (pyRequires)¶
plugin.json puede declarar requisitos de pip como una matriz en línea:
En el primer arranque del plugin, el editor aprovisiona un entorno virtual en
<AppLocalData>/PluginVenv/<id>/ (python -m venv + pip install, lo que
requiere acceso a la red esa única vez) y ejecuta el trabajador del plugin bajo el
intérprete de ese entorno. Los arranques posteriores lo reutilizan; cambiar
pyRequires vuelve a aprovisionarlo automáticamente (el entorno lleva un sello de
los requisitos para los que se construyó).
- Los fallos de aprovisionamiento (sin red, un requisito mal escrito) dejan el plugin listado pero no cargado, con el error de pip en el registro; el siguiente arranque lo reintenta.
- Desinstalar un plugin elimina su entorno virtual junto con la carpeta del plugin
(un entorno virtual es dato derivado: se reconstruye a partir de
pyRequiressi alguna vez lo reinstalas).
Máquinas sin conexión o restringidas¶
Distribuye un entorno virtual preconstruido dentro del paquete, como una
carpeta venv/ en la raíz del plugin. Cuando existe, gana sobre todo lo demás: pip
no se ejecuta nunca. Constrúyelo en una máquina con el mismo sistema operativo y
la misma arquitectura, porque los entornos virtuales no son portátiles entre
plataformas.
Incluir el código (dependencias pequeñas de Python puro)¶
Para un único módulo de Python puro, incluirlo dentro de la carpeta del plugin sigue funcionando y evita por completo la maquinaria del entorno virtual:
# main.py
import os, sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "vendor"))
import your_dep
Permisos declarados¶
plugin.json puede llevar una matriz permissions (p. ej. ["network"]). La
página de Preferencias de Plugins la muestra en una columna Permisos de solo
lectura, para que los usuarios vean qué declara un plugin sobre sí mismo. Es una
declaración, no una imposición: el aislamiento es trabajo futuro.
Dónde van los datos con permiso de escritura¶
El directorio de plugins contiene código. Los datos de tiempo de ejecución
(cachés, configuración por usuario, índices) van a un directorio de datos aparte
por plugin que gestiona el anfitrión; ctx.data_dir() devuelve su ruta absoluta.
NO escribas en el directorio de plugins desde tu .py en tiempo de ejecución: la
desinstalación elimina toda la carpeta <Plugins>/<id>/, y las escrituras hechas
en otros puntos del árbol de plugins nunca se limpian.
Desplegar en otras máquinas¶
Distribuye el archivo .mteplugin: es autocontenido y se valida en el extremo
receptor. Un zip, un tarball o un clon de git de la carpeta en el directorio de
plugins por usuario también funcionan.
Activar y desactivar¶
La página de Preferencias de Plugins lista todos los plugins detectados (nativos y de Python, juntos) con las mismas columnas de origen y estado. Desactivar un plugin lo mantiene listado pero impide que su fábrica se invoque al arrancar: no se lanza ningún trabajador. Vuelve a activarlo y reinicia para recuperarlo.