Runtime environment & red lines
The host Python version, bundled libraries, how to ship private dependencies, and what you must never do.
Runtime environment
| Item | Fact |
|---|---|
| Python | The host is 3.11 – 3.12 |
| Core libraries bundled with the host | numpy, PySide6 (the full set, including QtWebSockets), torch, transformers, sounddevice, requests, httpx |
| Sandbox | None — plugins run with the same privileges as the main application |
| Runtime pip | Strictly forbidden |
Private dependencies: libs/ and vendor/
If you depend on a lightweight Python library the host does not bundle (opencc, deepl, openai, jieba…), never call pip at runtime. The standard approach:
Create
libs/orvendor/at the root of your plugin source:bashpip install <package_name> -t ./libsShip the dependency directory inside the MOD package.
When loading a plugin the host
PluginRegistrydetects them automatically and injects<plugin dir>/libsand<plugin dir>/vendorintosys.path, so the plugin itself and its child threads canimportthem directly.When the plugin is uninstalled, the host removes those paths from
sys.pathagain, keeping the global environment clean.
Heavy models / heavy runtimes: use a separate process + local HTTP, with the plugin only making requests. Or distribute them with Host runtimes / Model artifacts.
Prohibitions
| Prohibited | Reason |
|---|---|
os.system("pip install …") / installing packages with subprocess | Pollutes the user's environment, fails silently, no version control |
| Uploading microphone / caption / history data without permission | Privacy red line |
| Modifying the main application's global config / other plugins' config | Over-reach; only read and write plugins_config/<this plugin id> and plugin_data/<this plugin id> |
| Trojans / crypto mining / unauthorised background behaviour | Immediate ban |
Changing the main application's core glossary (src/transbox/ui/locales/*.json) | Override incrementally with the plugin's own locales/ |
Putting binaries/weights into data/models/ | That is a pure-weights directory; the user hitting "Clear cache" would damage it |
Packing tens of MB of binaries into the .tbmod | The upload channel caps at 20 MB |
Network
- Only access APIs / model sources you declared yourself.
- It is recommended to declare the capabilities you use in
permissions:
"permissions": ["net", "clipboard", "hotkey", "window"]| Value | Meaning |
|---|---|
net | Access the network |
clipboard | Read and write the clipboard |
hotkey | Register global hotkeys |
window | Create windows / change window properties |
permissions currently serves workshop display and auditing (it may become a gate in the future) — declaring a value does not mean it is automatically granted, but not declaring it is treated as concealment.
Credentials
- Have the user fill them in through
config_schema("type": "password", "is_secret": true); never hard-code private keys, personal paths, or absolute paths from a developer machine. - Storing a key in the plugin config is enough (the host isolates it per plugin); never write a key into the logs or into an
emit_eventpayload.
Where data lives
| Content | Location |
|---|---|
| Config | plugins_config/<plugin_id> (managed by the host) |
| Small state | host.get_plugin_kv() |
| Cache / files / reference audio | self.get_data_dir() → <install dir>/data/plugins/<plugin_id>/ |
| Model weights | Managed by the host (model_artifacts) |
Security tiers
Data plugins (theme / glossary / i18n) are relatively safer; script plugins (Python) are used at the user's own risk. The platform manually reviews script plugins, while data plugins and trusted authors can be published automatically.
The core team reserves the right to evolve this specification and to publish or unpublish plugins.
Related
- Packaging & size limit
- Publish channels
- Config & private data
- Layout & mod.json — the
permissionsfield
