Przejdź do treści

Pakowanie i instalacja

Wtyczka Pythona to folder z plugin.json i modułem Pythona. Instaluje się ją na dwa sposoby: spakowaną jako archiwum .mteplugin przez instalator edytora (zalecane) albo przez ręczne wrzucenie folderu do katalogu wtyczek.

Zacznij od szablonu

Gotowy do skopiowania starter leży w repo w Python/templates/plugin-template-python/ — trzy pliki (plugin.json, main.py, README.md) plus CLAUDE.md dla Claude'a. Zmień nazwę folderu na krótką nazwę swojej wtyczki, popraw cztery pola w plugin.json i zacznij pisać register(ctx). Zainstalowany SDK zawiera ten sam szablon w share/MTEPluginSDK/plugin-template-python/.

Układ folderu wtyczki

hello/
├── plugin.json      # required
└── main.py          # required; module name from plugin.json.module

Wszystko, czego wtyczka potrzebuje, musi siedzieć w tym folderze. Pod-importy działają, ale muszą być płaskie — kropkowane nazwy module w plugin.json to przyszłe rozszerzenie.

Możesz dodać dodatkowe pliki (README, LICENSE) — host ignoruje to, czego nie rozpoznaje.

Pakiety .mteplugin (zalecane)

Spakuj pliki wtyczki zipem i nadaj archiwum rozszerzenie .mteplugin (zwykły .zip też działa). Akceptowane są oba kształty:

hello.mteplugin              hello.mteplugin
├── plugin.json              └── hello-1.0.0/        # any folder name
└── main.py                      ├── plugin.json
                                 └── main.py

Pojedynczy folder opakowujący — naturalny wynik zipowania folderu — jest normalizowany: wtyczka zawsze instaluje się do <Plugins>/<id>/, kluczem jest id z manifestu, nigdy nazwa folderu w archiwum. Dlatego też instalacja wersji 2 wtyczki zastępuje wersję 1, zamiast stanąć obok.

Instaluj przez Preferencje → Wtyczki → Zainstaluj… i zrestartuj edytor.

Instaluj tylko pakiety, którym ufasz

Instalator sprawdza, że pakiet jest strukturalnie poprawny (niżej) — nie czyni niezaufanej wtyczki bezpieczną w działaniu. Po załadowaniu wtyczka działa z takim samym dostępem do Twoich plików, ustawień i sieci jak edytor i nie jest sandboksowana. Statyczna sonda register(...) nie wykonuje żadnego kodu przy instalacji, ale kod wtyczki wykonuje się przy następnym starcie. Traktuj .mteplugin (i wszelkie pliki konfiguracyjne/JSON, które niesie) jak nieznany program: instaluj tylko z zaufanego źródła. Pełne ostrzeżenie: Wtyczki.

Co waliduje instalator

Pakiet jest w pełni walidowany na jednorazowej kopii, zanim cokolwiek na dysku zostanie tknięte — zły pakiet nigdy nie naruszy istniejącej instalacji:

  1. plugin.json się parsuje, ma id, apiVersion zgadza się z edytorem, entry to "python", a module jest obecny.
  2. Spis archiwum jest bezpieczny: brak ścieżek bezwzględnych i wpisów .., najwyżej 10 000 wpisów, najwyżej 256 MiB po rozpakowaniu i przynajmniej jeden plik .py.
  3. Po rozpakowaniu do katalogu roboczego zadeklarowany <module>.py istnieje i deklaruje def register(...) na najwyższym poziomie — ta sama statyczna sonda co przy wykrywaniu. Przy instalacji nie wykonuje się żaden kod Pythona.

Każde niepowodzenie daje czytelny komunikat błędu i zostawia wtyczki edytora nietknięte.

Aktualizacja i odinstalowanie

  • Instalacja pakietu, którego id jest już zainstalowane, zastępuje go. Jeśli ta wtyczka jest właśnie załadowana, aktualizacja jest odkładana i stosowana przy następnym starcie.
  • Odinstalowuj z tej samej strony Preferencji; usunięcie też następuje przy następnym starcie, gdy nic nie jest załadowane.
  • Wtyczek dołączonych (wbudowanych) nie da się nadpisać zainstalowanym pakietem o tym samym id.

Instalacja ręczna (wrzucenie folderu)

Edytor odkrywa wtyczki w dwóch katalogach przy każdym starcie:

  1. Dołączone — obok pliku wykonywalnego, w <exe-dir>/Plugins/. Wbudowane wtyczki (np. HelloPython) mieszkają tutaj.
  2. Użytkownika — per użytkownik, zapisywalny. Na Windows to %LOCALAPPDATA%/MTE/Plugins/, na macOS ~/Library/Application Support/MTE/Plugins/, na Linuksie ~/.local/share/MTE/Plugins/.

Skanowane są oba. Jeśli to samo id występuje w obu, wygrywa pierwsze wystąpienie (dołączone mają pierwszeństwo). Zrestartuj edytor, aby przejął nowe foldery — gorące przeładowanie nie jest wspierane.

Dwa akceptowane układy

Skan szuka plugin.json albo bezpośrednio w katalogu wtyczek (luzem), albo w jednym poziomie bezpośredniego podkatalogu (folder per wtyczka):

Plugins/
├── plugin.json         # loose -- one plugin at the top level
├── main.py
└── hello/              # per-plugin folder -- one plugin
    ├── plugin.json
    └── main.py

Folder per wtyczka to układ zalecany; taki kształt tworzy instalator.

Zależności (pyRequires)

plugin.json może deklarować wymagania pip jako tablicę inline:

"pyRequires": ["requests>=2.31"]

Przy pierwszym uruchomieniu wtyczki edytor przygotowuje środowisko wirtualne w <AppLocalData>/PluginVenv/<id>/ (python -m venv + pip install, co ten jeden raz wymaga dostępu do sieci) i uruchamia workera wtyczki pod interpreterem tego venv. Kolejne starty go używają ponownie; zmiana pyRequires automatycznie przygotowuje venv od nowa (venv nosi stempel wymagań, dla których został zbudowany).

  • Niepowodzenia provisioning-u (brak sieci, literówka w wymaganiu) zostawiają wtyczkę na liście, ale nie załadowaną, z błędem pip w logu; następny start ponawia próbę.
  • Odinstalowanie wtyczki usuwa jej venv razem z folderem wtyczki (venv to dane pochodne — przy ewentualnej reinstalacji odbuduje się z pyRequires).

Maszyny offline / zablokowane

Dostarcz zbudowany wcześniej venv w pakiecie jako folder venv/ w korzeniu wtyczki. Gdy jest obecny, wygrywa ze wszystkim — pip nigdy się nie uruchamia. Zbuduj go na maszynie o tym samym OS/architekturze, bo venvy nie są przenośne między platformami.

Vendoring (małe zależności pure-Python)

Dla pojedynczego modułu pure-Python vendoring wewnątrz folderu wtyczki wciąż działa i całkowicie omija maszynerię venv:

# main.py
import os, sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "vendor"))

import your_dep

Deklarowane uprawnienia

plugin.json może nieść tablicę permissions (np. ["network"]). Strona Preferencji Wtyczek pokazuje ją w kolumnie Uprawnienia tylko do odczytu, aby użytkownicy widzieli, co wtyczka o sobie deklaruje. To deklaracja, nie egzekwowanie — sandboxing to przyszła praca.

Gdzie idą dane zapisywalne

Katalog wtyczek trzyma kod. Dane działania (cache, konfiguracja per użytkownik, indeksy) idą do osobnego katalogu danych per wtyczka zarządzanego przez hosta — ctx.data_dir() zwraca jego ścieżkę bezwzględną. NIE pisz do katalogu wtyczek ze swojego .py w czasie działania; odinstalowanie usuwa cały folder <Plugins>/<id>/, a zapisy zrobione gdzie indziej w drzewie wtyczek nigdy nie są sprzątane.

Wdrażanie na inne maszyny

Wyślij plik .mteplugin — jest samowystarczalny i walidowany po stronie odbiorcy. Zip/tarball/git-clone folderu do katalogu wtyczek użytkownika też działa.

Włączanie / wyłączanie

Strona Preferencji Wtyczek wymienia każdą wykrytą wtyczkę (natywne + Python razem) z tymi samymi kolumnami pochodzenia/stanu. Wyłączenie wtyczki zostawia ją na liście, ale zapobiega wywołaniu jej fabryki przy starcie — worker nie jest tworzony. Włącz ponownie i zrestartuj, aby wróciła.