Plugin API 1.0
A stable versioned extension boundary for trusted local Python plugins, plus a separate isolated subprocess runtime.
Stable API surface
New integrations should import the stable contract from pysh.api. The compatibilitypysh.contracts path remains supported for the same Plugin API version objects.
from pysh.api import PLUGIN_API_VERSION, PluginHooks, PluginMeta
assert PLUGIN_API_VERSION == (1, 0)
Plugin class
A trusted plugin module defines exactly one valid plugin class with name, version, and api_version. Zero or multiple valid classes are rejected deterministically.
class ExamplePlugin:
name = "example"
version = "0.1.0"
api_version = (1, 0)
def register(self, api):
api.register_command("hello", self.hello)
def hello(self, argv):
print("hello from plugin")
return 0
Plugin locations
- ✓User plugins: ~/.config/pysh/plugins/*.py
- ✓Project-local plugins: .pysh/plugins/*.py
- ✓Plugin discovery is non-recursive
- ✓The plugin infrastructure performs no auto-installation, marketplace lookup, or network access
Explicit enablement
Plugins never load merely because a file exists. Enable trusted user plugins explicitly from~/.pyshrc.py. Project plugins require a second explicit opt-in.
def configure(shell):
shell.enable_plugin("example")
# Only if this project-local trust boundary is intended:
shell.enable_project_plugins()
shell.enable_plugin("project_tool")
Registration API
- ✓api.register_command(name, handler)
- ✓api.register_completer(command_name, completer)
- ✓api.register_prompt_segment(name, renderer, position="end")
- ✓api.on_startup(callback)
- ✓api.on_shutdown(callback)
- ✓api.on_env_change(callback)
Plugin commands cannot override PySH builtins. Callback failures are contained: command failures return status 1, completion failures return no plugin candidates, prompt failures skip the segment, and lifecycle-hook failures do not abort startup or shutdown.
Plugin configuration
Optional plugin-specific TOML is stored under~/.config/pysh/plugins/<plugin-name>.toml. TOML is data only and does not enable plugin code. A plugin reads it at runtime through the configuration API.
Isolated plugins
PySH v1 also defines a separate manifest-driven subprocess runtime with bounded IPC, explicit capability grants, resource budgets, descriptor hygiene, and parent-mediated broker operations. It does not replace trusted Plugin API 1.0 plugins.