- Add startAPIServer function to start gRPC server on random port
- Add APIServerRegistrar type to break import cycle with apiserver package
- Modify WithCommandFromManifest to accept apiImpl and registrar
- Update configurePythonCommand to start API server and set MATTERMOST_PLUGIN_API_TARGET env var
- Add apiServerCleanup field to supervisor struct for cleanup on shutdown
- Add SetAPIServerRegistrar method to Environment for dependency injection
- Wire up API server registrar in app/plugin.go
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When pluginInfo.Path is relative (e.g., "plugins/com.mattermost.hello-python"),
the venv interpreter path was also relative. exec.Command needs an absolute
path to find the executable when cmd.Dir is set.
Fix: Convert the venv path to absolute using filepath.Abs before returning.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When cmd.Dir is set, command arguments are resolved relative to that
directory. The code was passing the full path (including plugin dir)
as the script argument while also setting cmd.Dir to the plugin dir,
causing Python to look for the script at a duplicated path like:
plugins/com.mattermost.hello-python/plugins/com.mattermost.hello-python/plugin.py
Fix: Pass just the executable name (e.g., "plugin.py") to the command
since cmd.Dir is already set to the plugin directory. The full path
is still used for the existence check before command creation.
Also removes debug logging that was added for diagnosis.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace transitional props.runtime hack with proper manifest field detection.
Now prioritizes Server.Runtime="python" over .py extension fallback.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add helper functions for Python plugin support in the supervisor:
- isPythonPlugin: detects Python plugins via .py extension or props.runtime
- findPythonInterpreter: discovers venv-first Python with PATH fallback
- sanitizePythonScriptPath: validates script paths preventing traversal
- buildPythonCommand: creates exec.Cmd with proper working dir and WaitDelay
- WithCommandFromManifest: unified option for Go and Python plugin commands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>