Build & Install the Example Plugin
Praxrr ships a runnable example plugin at
examples/plugins/sync-preview-observer/ — a Go plugin built with the
Extism Go PDK and compiled to WASM with TinyGo. It targets the wired
sync.previewComputed.observe extension point. This page is the
copy-paste walkthrough to build it, install it into PLUGINS_DIR, and
confirm the host discovers, validates, and registers its manifest.
Its praxrr.plugin.json is the minimal valid manifest for the wired
preview point. See the Manifest reference for the
full validation rules; the example declares:
| Field | Value |
|---|---|
apiVersion |
"1" |
id |
dev.praxrr.examples.sync-preview-observer |
name |
Sync Preview Observer (Example) |
version |
1.0.0 |
runtime |
wasm |
entry |
plugin.wasm |
extensionPoints |
["sync.previewComputed.observe"] |
capabilities |
["read:sync-preview"] |
description |
a short human-readable string (optional) |
Prerequisites
Section titled “Prerequisites”You need one of:
- Docker — to run the pinned TinyGo image (recommended; reproducible).
- TinyGo installed locally — for the native fallback build.
From the example directory, make build runs the pinned Docker build:
docker run --rm -v "$PWD":/src -w /src \ tinygo/tinygo:0.41.1 \ tinygo build -target wasi -o plugin.wasm main.goIf you have TinyGo installed locally, the native fallback is the same compile without Docker:
tinygo build -target wasi -o plugin.wasm main.goEither path writes plugin.wasm next to the manifest. That artifact is
git-ignored and never committed — you rebuild it locally.
Install into PLUGINS_DIR
Section titled “Install into PLUGINS_DIR”The plugin subsystem is off by default. Enable it and point it at an existing directory:
# Enable plugins in the UI (Apps → Plugins), then optionally:mkdir -p /path/to/praxrr-pluginsexport PLUGINS_DIR=/path/to/praxrr-pluginsPLUGINS_ENABLED accepts 1, true, yes, or on. PLUGINS_DIR is
never auto-created — you must mkdir it yourself. (When unset it defaults
to <APP_BASE_PATH>/plugins, but the host still will not create it.)
Then copy the plugin directory — the manifest plus the built plugin.wasm
— into PLUGINS_DIR:
make install PLUGINS_DIR=/path/to/praxrr-pluginsRestart Praxrr so the host re-scans PLUGINS_DIR on the next boot.
Confirm it worked
Section titled “Confirm it worked”On boot the host scans each immediate subdirectory of PLUGINS_DIR for a
praxrr.plugin.json manifest, then discovers → validates → registers
the example. Confirm success only through the discovery and
registration lines in the logs — the registry stores the plugin in state
registered.
Do not expect any output from the plugin itself. Because no WASM runtime exists yet, an observe dispatch no-ops and logs, at debug level:
Plugin runtime unavailable; observe dispatch skippedThere is never a log line or side effect implying the guest ran. If you see the registration in the logs, the walkthrough succeeded.
What the plugin would observe
Section titled “What the plugin would observe”Once the Phase-2 runtime lands, a plugin registered for
sync.previewComputed.observe would receive a redacted, JSON-safe
snapshot with exactly four fields:
{ "arrType": "radarr", "instanceId": 3, "summary": {}, "sections": []}This is the read:sync-preview allow-list projection over the internal
preview result; every other field is dropped before a plugin could ever
see it. See the observe snapshot reference
for the exact shape and its guarantees.