wolfhece._plugin_loader
Companion plugin loader.
Discovers, validates, and loads companion plugins from a plugins directory.
Plugin layout
Each plugin lives in its own subdirectory containing at least two files:
plugin.tomlMachine-readable metadata (required). See the schema below.
companion.pyPython module that defines (and exports) the companion class (required).
Example directory tree:
wolfhece/data/plugins/
├── _template/ ← ignored (starts with ``_``)
│ ├── plugin.toml
│ └── companion.py
└── my_feature/
├── plugin.toml
└── companion.py
plugin.toml schema
[plugin]
name = "my_feature" # unique slug (required)
display_name = "My Feature" # human-readable label (defaults to name)
version = "1.0.0" # semver string (required)
author = "Jane Doe" # (required)
email = "jane@example.com" # optional
description = "Short description." # optional
entry_class = "MyFeatureCompanion" # companion class in companion.py (required)
created = "2026-01-15" # optional ISO date
updated = "2026-05-22" # optional ISO date
[compatibility]
requires_wolfhece = ">=2.2" # optional, informational only
min_python = "3.11" # optional "major.minor" constraint
Warning
Loading a plugin executes arbitrary Python code from companion.py.
Only load plugins from trusted sources.
Module Contents
- class wolfhece._plugin_loader.PluginManifest[source]
Parsed metadata from
plugin.toml.- classmethod from_dict(data: dict) PluginManifest[source]
Build from a parsed
plugin.tomldict.
- class wolfhece._plugin_loader.PluginInfo[source]
A discovered plugin — manifest, resolved class, and runtime status.
- manifest: PluginManifest[source]
- exception wolfhece._plugin_loader.PluginValidationError(path: pathlib.Path, errors: list[str])[source]
Bases:
ValueError
Raised when a plugin directory does not pass validation.
- wolfhece._plugin_loader.validate_plugin_dir(plugin_dir: pathlib.Path) list[str][source]
Return a list of validation error strings (empty list = OK).
Checks:
The path is an existing directory.
plugin.tomlexists and is valid TOML.Required keys
name,version,author,entry_classare present.nameis a slug-like identifier (only letters, digits,-,_).min_pythonconstraint is satisfied by the running interpreter (if set).companion.pyexists.
This function never raises — all problems are returned as strings.
- wolfhece._plugin_loader.load_plugin(plugin_dir: pathlib.Path) PluginInfo[source]
Load and validate one plugin from plugin_dir.
- Parameters:
plugin_dir – Path to the plugin subdirectory.
- Raises:
PluginValidationError – if the directory fails validation.
ImportError – if
companion.pycannot be imported.AttributeError – if the entry class is not found in the module.
TypeError – if the entry class does not subclass
AbstractCompanion.
- Returns:
A fully populated
PluginInfowithcompanion_classset.
- wolfhece._plugin_loader.discover_plugins(directory: pathlib.Path | str | None = None) list[PluginInfo][source]
Discover all plugin directories under directory.
Skips subdirectories whose name starts with
_or.(template / draft folders) so they can coexist safely with live plugins.Invalid or failing plugins are not raised — they are returned as
PluginInfoobjects withload_errorset andcompanion_class=None.When two valid plugins share the same name, the first one (alphabetical) wins and the duplicate is logged then skipped.
- Parameters:
directory – Root plugins directory. Defaults to
wolfhece/data/plugins.- Returns:
List of
PluginInfoobjects, one per discovered subdirectory (failures included).
- wolfhece._plugin_loader._make_error_info(sub: pathlib.Path, error_msg: str) PluginInfo[source]
Build a placeholder PluginInfo for a plugin that failed to load.
- wolfhece._plugin_loader.discover_all_plugins(user_directory: pathlib.Path | str | None = None) list[PluginInfo][source]
Discover both built-in and user plugins, returning a combined list.
Built-in plugins (from
BUILTIN_PLUGINS_DIR) are listed first, followed by user plugins (from user_directory orPLUGINS_DIR). Duplicate plugin names (same slug in both directories) are resolved in favour of the built-in version — the user plugin is skipped with a warning.- Parameters:
user_directory – Directory to scan for user plugins. Defaults to
PLUGINS_DIR.- Returns:
Combined list of
PluginInfoobjects.