Adding a Plugin
Adding a Plugin
Follow core-vs-plugins-structure-philosophy: a new capability is a new file
in the matching plugin folder. You register nothing; discovery finds it.
Add an integration (most common)
- Copy
app/integrations/_TEMPLATE.py→app/integrations/<name>_tools.py. - Fill in the
FEATUREheader (see the-feature-header) and theTOOLSlist. - Done —
inject_integration_tools()auto-discovers it. Do not edit
app/tools/loader.py or any core file.
Add another plugin type
Each folder auto-discovers a specific shape:
- Event source —
app/events/sources/<name>.pyexposingsource_cls
(an EventSource subclass) + a FEATURE.
- Channel —
app/communications/plugins/<name>.pyexposingplugin_cls
(a CommunicationPlugin subclass) + a FEATURE.
- Connector —
app/connectors/<name>.pywith aConnectorsubclass whose
type_name is its id. (The data_sources.type CHECK was relaxed, so no
schema edit is needed.)
- Secrets vault —
app/secrets/<name>.pywith aSecretsBackendsubclass
(its .name is the provider id) + a FEATURE.
- Encryption method —
app/encryption/<name>.pywith anEncryptionBackend
subclass + a FEATURE whose id is the level name.
- Payment processor —
app/billing/processors/<name>.pyexposing
processor_cls + a FEATURE.
- Scheduler provider —
app/scheduler/providers/<name>.pyexposing a
PROVIDER dict (id/display_name/fields/cls) + a FEATURE.
Removing a capability
Delete its file. Nothing else references it. (For the registry subsystems the
hard-wired fallback covers the irreducible core; everything else is gone.)
Verify
Open App Config → Features (the-feature-catalog-and-discovery) — your
plugin should appear with its declared status.