# Creating Plugins This guide covers how to build, package, and install a Windshift plugin. ## Prerequisites - An Extism-compatible language SDK (Rust, Go, JavaScript, C, etc.) - Basic understanding of WebAssembly Extism provides PDKs (Plugin Development Kits) for multiple languages. See [extism.org](https://extism.org/) for the full list. ## Project Structure ``` my-plugin/ ├── manifest.json # Plugin metadata and extensions ├── src/ # Plugin source code ├── plugin.wasm # Compiled WASM binary └── index.html # Optional UI (for iframe extensions) ``` ## Manifest Every plugin requires a `manifest.json`: ```json { "name": "my-plugin", "version": "1.0.0", "description": "What this plugin does", "entryPoint": "plugin.wasm", "extensions": [] } ``` ### Fields | Field | Required | Description | |-------|----------|-------------| | `name` | Yes | Unique plugin identifier | | `version` | Yes | Semantic version | | `description` | Yes | Human-readable description | | `entryPoint` | Yes | Path to the WASM binary | | `extensions` | No | List of UI extension registrations | ### Extensions To add a UI tab in the admin panel: ```json { "extensions": [ { "point": "admin.tab", "id": "my-plugin-tab", "label": "My Plugin", "displayMode": "iframe", "component": "index.html", "group": "Tools" } ] } ``` | Field | Description | |-------|-------------| | `point` | Extension point (e.g., `admin.tab`) | | `id` | Unique extension identifier | | `label` | Display name in the UI | | `displayMode` | How to render: `iframe` for HTML content | | `component` | Path to the HTML file | | `group` | Group name in the admin sidebar | ## Writing Plugin Code Plugins export functions that Windshift calls, and import host functions to interact with the platform. ### Example (Go with Extism PDK) ```go package main import ( "github.com/extism/go-pdk" ) //export run func run() int32 { // Call a host function pdk.Log(pdk.LogInfo, "Plugin executing") // Read input input := pdk.Input() // Do work... // Write output pdk.OutputString("done") return 0 } func main() {} ``` ### Example (JavaScript with Extism PDK) ```javascript function run() { Host.log("info", "Plugin executing"); const input = Host.inputString(); // Do work... Host.outputString("done"); return 0; } module.exports = { run }; ``` ## Building Compile your plugin to a WASM binary using the Extism toolchain for your language: ```bash # Go tinygo build -o plugin.wasm -target wasi . # Rust cargo build --target wasm32-wasi --release cp target/wasm32-wasi/release/my_plugin.wasm plugin.wasm # JavaScript (using Extism JS PDK) extism-js src/index.js -o plugin.wasm ``` ## Installing Place the plugin directory (containing `manifest.json` and `plugin.wasm`) in Windshift's plugin directory. Windshift scans for plugins at startup. Plugins can be enabled/disabled from the admin panel without restarting the server. ## Resource Limits Plugins run with these default constraints: | Limit | Value | |-------|-------| | Execution timeout | 5 seconds | | Memory | 64 MB | Plugins that exceed these limits are terminated automatically.