docs: update README for .ndp plugin packaging and installation instructions

Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Deluan 2025-12-28 21:43:18 -05:00
parent e52b757cd4
commit 4e392f7b07
10 changed files with 178 additions and 157 deletions

View File

@ -29,38 +29,41 @@ Navidrome supports WebAssembly (Wasm) plugins for extending functionality. Plugi
### 1. Create a minimal plugin ### 1. Create a minimal plugin
Create `main.go`:
```go ```go
package main package main
import ( import "github.com/extism/go-pdk"
"encoding/json"
"github.com/extism/go-pdk"
)
//go:wasmexport nd_manifest
func ndManifest() int32 {
manifest := map[string]string{
"name": "My Plugin",
"author": "Your Name",
"version": "1.0.0",
}
out, _ := json.Marshal(manifest)
pdk.Output(out)
return 0
}
func main() {} func main() {}
// Implement your capability functions here
``` ```
### 2. Build with TinyGo Create `manifest.json`:
```json
{
"name": "My Plugin",
"author": "Your Name",
"version": "1.0.0"
}
```
### 2. Build with TinyGo and package as .ndp
```bash ```bash
tinygo build -o my-plugin.wasm -target wasip1 -buildmode=c-shared . # Compile to WebAssembly
tinygo build -o plugin.wasm -target wasip1 -buildmode=c-shared .
# Package as .ndp (zip archive)
zip -j my-plugin.ndp manifest.json plugin.wasm
``` ```
### 3. Install ### 3. Install
Copy `my-plugin.wasm` to your Navidrome plugins folder and enable plugins in your config: Copy `my-plugin.ndp` to your Navidrome plugins folder and enable plugins in your config:
```toml ```toml
[Plugins] [Plugins]
@ -74,23 +77,31 @@ Folder = "/path/to/plugins"
### What is a Plugin? ### What is a Plugin?
A Navidrome plugin is a WebAssembly (`.wasm`) file that: A Navidrome plugin is an `.ndp` package file (zip archive) containing:
1. **Exports `nd_manifest`** Returns JSON describing the plugin 1. **`manifest.json`** Plugin metadata (name, author, version, permissions)
2. **Exports capability functions** Implements one or more capabilities 2. **`plugin.wasm`** Compiled WebAssembly module with capability functions
### Plugin Package Structure
```
my-plugin.ndp (zip archive)
├── manifest.json # Required: Plugin metadata
└── plugin.wasm # Required: Compiled WebAssembly module
```
### Plugin Naming ### Plugin Naming
Plugins are identified by their **filename** (without `.wasm` extension), not the manifest `name` field: Plugins are identified by their **filename** (without `.ndp` extension), not the manifest `name` field:
- `my-plugin.wasm` → plugin ID is `my-plugin` - `my-plugin.ndp` → plugin ID is `my-plugin`
- The manifest `name` is the display name shown in the UI - The manifest `name` is the display name shown in the UI
This allows users to have multiple instances of the same plugin with different configs by renaming the files. This allows users to have multiple instances of the same plugin with different configs by renaming the files.
### The Manifest ### The Manifest
Every plugin must export `nd_manifest` returning JSON: Every plugin must include a `manifest.json` file. Example:
```json ```json
{ {
@ -110,8 +121,6 @@ Every plugin must export `nd_manifest` returning JSON:
**Required fields:** `name`, `author`, `version` **Required fields:** `name`, `author`, `version`
**Capabilities are auto-detected** from which functions your plugin exports. You don't declare them in the manifest.
--- ---
## Capabilities ## Capabilities
@ -572,12 +581,12 @@ Enabled = true
Folder = "/path/to/plugins" # Default: DataFolder/plugins Folder = "/path/to/plugins" # Default: DataFolder/plugins
AutoReload = true # Auto-reload on file changes (dev mode) AutoReload = true # Auto-reload on file changes (dev mode)
LogLevel = "debug" # Plugin-specific log level LogLevel = "debug" # Plugin-specific log level
CacheSize = "100MB" # Compilation cache size limit CacheSize = "200MB" # Compilation cache size limit
``` ```
### Plugin Configuration ### Plugin Configuration
Plugin configuration is managed through the Navidrome web UI. Navigate to the Plugins page, select a plugin, and edit its configuration as a JSON object with string key-value pairs. Plugin configuration is managed through the Navidrome web UI. Navigate to the Plugins page, select a plugin, and edit its configuration as key-value pairs.
Access configuration values in your plugin: Access configuration values in your plugin:
@ -607,8 +616,31 @@ Plugins can be written in any language that compiles to WebAssembly. We recommen
```bash ```bash
# Install TinyGo: https://tinygo.org/getting-started/install/ # Install TinyGo: https://tinygo.org/getting-started/install/
# Build # Build WebAssembly module
tinygo build -o my-plugin.wasm -target wasip1 -buildmode=c-shared . tinygo build -o plugin.wasm -target wasip1 -buildmode=c-shared .
# Package as .ndp
zip -j my-plugin.ndp manifest.json plugin.wasm
```
### Rust
```bash
# Build WebAssembly module
cargo build --release --target wasm32-unknown-unknown
# Package as .ndp
zip -j my-plugin.ndp manifest.json target/wasm32-unknown-unknown/release/plugin.wasm
```
### Python (with extism-py)
```bash
# Build WebAssembly module (requires extism-py installed)
extism-py plugin.wasm -o plugin.wasm *.py
# Package as .ndp
zip -j my-plugin.ndp manifest.json plugin.wasm
``` ```
### Using XTP CLI (Scaffolding) ### Using XTP CLI (Scaffolding)
@ -625,8 +657,9 @@ xtp plugin init \
--path ./my-agent \ --path ./my-agent \
--name my-agent --name my-agent
# Build # Build and package
cd my-agent && xtp plugin build cd my-agent && xtp plugin build
zip -j my-agent.ndp manifest.json dist/plugin.wasm
``` ```
See [schemas/README.md](schemas/README.md) for available schemas. See [schemas/README.md](schemas/README.md) for available schemas.
@ -671,16 +704,18 @@ Plugins run in a secure WebAssembly sandbox:
## Runtime Management ## Runtime Management
### Auto-Reload (Development) ### Auto-Reload
With `AutoReload = true`, Navidrome watches the plugins folder and automatically reloads plugins when files change. With `AutoReload = true`, Navidrome watches the plugins folder and automatically detects when `.ndp` files are added, modified, or removed. When a plugin file changes, the plugin is disabled and its metadata is re-read from the archive.
### Programmatic Control If the `AutoReload` setting is disabled, Navidrome needs to be restarted to pick up plugin changes.
Plugins can be enabled/disabled via the Navidrome UI or API. The plugin state is persisted in the database. ### Enabling/Disabling Plugins
Plugins can be enabled/disabled via the Navidrome UI. The plugin state is persisted in the database.
### Important Notes ### Important Notes
- **In-flight requests** When reloading, existing requests complete before the new version takes over - **In-flight requests** When reloading, existing requests complete before the new version takes over
- **Config changes** Plugin configuration is read at load time; changes require a reload - **Config changes** Changes to the plugin configuration in the UI are applied immediately
- **Cache persistence** The in-memory cache is cleared when a plugin is unloaded - **Cache persistence** The in-memory cache is cleared when a plugin is unloaded

View File

@ -23,18 +23,20 @@ This folder contains example plugins demonstrating various capabilities and lang
- **Python plugins:** [extism-py](https://github.com/extism/python-pdk) - **Python plugins:** [extism-py](https://github.com/extism/python-pdk)
- **Rust plugins:** [Rust](https://rustup.rs/) with `wasm32-unknown-unknown` target - **Rust plugins:** [Rust](https://rustup.rs/) with `wasm32-unknown-unknown` target
### Build All (Go plugins) ### Build All Plugins
```bash ```bash
make all make all
``` ```
This creates `.ndp` package files for each plugin.
### Build Individual Plugin ### Build Individual Plugin
```bash ```bash
make minimal.wasm make minimal.ndp
make wikimedia.wasm make wikimedia.ndp
make discord-rich-presence.wasm make discord-rich-presence.ndp
``` ```
### Clean ### Clean
@ -47,15 +49,15 @@ make clean
### With Extism CLI ### With Extism CLI
Test any plugin without running Navidrome: Test any plugin without running Navidrome. First extract the `.wasm` file from the `.ndp` package:
```bash ```bash
# Install: https://extism.org/docs/install # Install: https://extism.org/docs/install
# Test manifest # Extract the wasm file from the package
extism call minimal.wasm nd_manifest --wasi unzip -p minimal.ndp plugin.wasm > minimal.wasm
# Test with input # Test a capability function
extism call minimal.wasm nd_get_artist_biography --wasi \ extism call minimal.wasm nd_get_artist_biography --wasi \
--input '{"id":"1","name":"The Beatles"}' --input '{"id":"1","name":"The Beatles"}'
``` ```
@ -63,6 +65,7 @@ extism call minimal.wasm nd_get_artist_biography --wasi \
For plugins that make HTTP requests, allow the hosts: For plugins that make HTTP requests, allow the hosts:
```bash ```bash
unzip -p wikimedia.ndp plugin.wasm > wikimedia.wasm
extism call wikimedia.wasm nd_get_artist_biography --wasi \ extism call wikimedia.wasm nd_get_artist_biography --wasi \
--input '{"id":"1","name":"Yussef Dayes"}' \ --input '{"id":"1","name":"Yussef Dayes"}' \
--allow-host "query.wikidata.org" \ --allow-host "query.wikidata.org" \
@ -71,7 +74,7 @@ extism call wikimedia.wasm nd_get_artist_biography --wasi \
### With Navidrome ### With Navidrome
1. Copy the `.wasm` file to your plugins folder 1. Copy the `.ndp` file to your plugins folder
2. Enable plugins in `navidrome.toml`: 2. Enable plugins in `navidrome.toml`:
```toml ```toml
[Plugins] [Plugins]
@ -92,8 +95,9 @@ Copy the [minimal](minimal/) example and modify:
```bash ```bash
cp -r minimal my-plugin cp -r minimal my-plugin
cd my-plugin cd my-plugin
# Edit main.go # Edit main.go and manifest.json
tinygo build -o my-plugin.wasm -target wasip1 -buildmode=c-shared . tinygo build -o plugin.wasm -target wasip1 -buildmode=c-shared .
zip -j my-plugin.ndp manifest.json plugin.wasm
``` ```
### Option 2: Bootstrap with XTP CLI ### Option 2: Bootstrap with XTP CLI
@ -108,6 +112,11 @@ xtp plugin init \
--template go \ --template go \
--path ./my-plugin \ --path ./my-plugin \
--name my-plugin --name my-plugin
# Then create manifest.json and package
cd my-plugin
xtp plugin build
zip -j my-plugin.ndp manifest.json dist/plugin.wasm
``` ```
Available schemas in [../schemas/](../schemas/): Available schemas in [../schemas/](../schemas/):

View File

@ -23,18 +23,19 @@ A Python example plugin that fetches album cover images from the [Cover Art Arch
From the `plugins/examples` directory: From the `plugins/examples` directory:
```bash ```bash
make coverartarchive-py.wasm make coverartarchive-py.ndp
``` ```
Or directly: Or directly:
```bash ```bash
extism-py plugin/__init__.py -o coverartarchive-py.wasm extism-py plugin/__init__.py -o plugin.wasm
zip -j coverartarchive-py.ndp manifest.json plugin.wasm
``` ```
## Installation ## Installation
1. Copy `coverartarchive-py.wasm` to your Navidrome plugins folder 1. Copy `coverartarchive-py.ndp` to your Navidrome plugins folder
2. Enable plugins in `navidrome.toml`: 2. Enable plugins in `navidrome.toml`:
```toml ```toml
@ -50,15 +51,10 @@ extism-py plugin/__init__.py -o coverartarchive-py.wasm
## Testing ## Testing
Test the manifest: Extract the wasm file and test:
```bash
extism call coverartarchive-py.wasm nd_manifest --wasi
```
Test album image retrieval (using Portishead's "Dummy" MBID):
```bash ```bash
unzip -p coverartarchive-py.ndp plugin.wasm > coverartarchive-py.wasm
extism call coverartarchive-py.wasm nd_get_album_images --wasi \ extism call coverartarchive-py.wasm nd_get_album_images --wasi \
--input '{"name":"Dummy","artist":"Portishead","mbid":"76df3287-6cda-33eb-8e9a-044b5e15ffdd"}' \ --input '{"name":"Dummy","artist":"Portishead","mbid":"76df3287-6cda-33eb-8e9a-044b5e15ffdd"}' \
--allow-host "coverartarchive.org" --allow-host "archive.org" --allow-host "coverartarchive.org" --allow-host "archive.org"

View File

@ -14,15 +14,11 @@ This is a WebSocket-based WASM plugin for Navidrome that displays real-time cryp
Configure in the Navidrome UI (Settings → Plugins → crypto-ticker): Configure in the Navidrome UI (Settings → Plugins → crypto-ticker):
```json | Key | Description | Default |
{ |-----------|----------------------------------------------------------------------|-----------|
"tickers": "BTC,ETH,SOL,MATIC" | `tickers` | Comma-separated list of cryptocurrency symbols (e.g., `BTC,ETH,SOL`) | `BTC,ETH` |
}
```
- `tickers` is a comma-separated list of cryptocurrency symbols The plugin will append `-USD` to any symbol without a trading pair specified.
- The plugin will append `-USD` to any symbol without a trading pair specified
- Default: `BTC,ETH` if not configured
## How it Works ## How it Works
@ -40,19 +36,23 @@ This plugin was scaffolded using XTP CLI:
xtp plugin init --schema-file ../schemas/websocket_callback.yaml --template go --path ./crypto-ticker --name crypto-ticker xtp plugin init --schema-file ../schemas/websocket_callback.yaml --template go --path ./crypto-ticker --name crypto-ticker
``` ```
To build the plugin to WASM: To build the plugin and package as `.ndp`:
```bash ```bash
# Using TinyGo (recommended - smaller binary) # Using TinyGo (recommended - smaller binary)
tinygo build -o crypto-ticker.wasm -target wasip1 -buildmode=c-shared . tinygo build -o plugin.wasm -target wasip1 -buildmode=c-shared .
zip -j crypto-ticker.ndp manifest.json plugin.wasm
```
# Or using standard Go Or from the `plugins/examples/` directory:
GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o crypto-ticker.wasm .
```bash
make crypto-ticker.ndp
``` ```
## Installation ## Installation
Copy the resulting `crypto-ticker.wasm` to your Navidrome plugins folder. Copy the resulting `crypto-ticker.ndp` to your Navidrome plugins folder.
## Example Output ## Example Output

View File

@ -63,34 +63,30 @@ To work within this model the plugin stores no in-memory state. Connections are
Configure in the Navidrome UI (Settings → Plugins → discord-rich-presence): Configure in the Navidrome UI (Settings → Plugins → discord-rich-presence):
```json | Key | Description | Example |
{ |------------|----------------------------------------------------------|--------------------------------|
"clientid": "123456789012345678", | `clientid` | Your Discord application ID | `123456789012345678` |
"users": "alice:token123,bob:token456" | `users` | Comma-separated list of `username:token` pairs | `alice:token123,bob:token456` |
}
```
- `ClientID` is your Discord application ID
- `Users` is a comma-separated list of `username:token` pairs used for authorization
## Building ## Building
From the `plugins/examples/` directory: From the `plugins/examples/` directory:
```sh ```sh
make discord-rich-presence.wasm make discord-rich-presence.ndp
``` ```
Or manually: Or manually:
```sh ```sh
cd discord-rich-presence cd discord-rich-presence
tinygo build -target wasip1 -buildmode=c-shared -o ../discord-rich-presence.wasm . tinygo build -target wasip1 -buildmode=c-shared -o plugin.wasm .
zip -j discord-rich-presence.ndp manifest.json plugin.wasm
``` ```
## Installation ## Installation
Place the resulting `discord-rich-presence.wasm` in your Navidrome plugins folder and enable plugins in your configuration: Place the resulting `discord-rich-presence.ndp` in your Navidrome plugins folder and enable plugins in your configuration:
```toml ```toml
[Plugins] [Plugins]
@ -100,21 +96,21 @@ Folder = "/path/to/plugins"
## Files ## Files
| File | Description | | File | Description |
|------|-------------| |----------------|---------------------------------------------------------|
| `main.go` | Plugin entry point, manifest, scrobbler implementation | | `main.go` | Plugin entry point, manifest, scrobbler implementation |
| `rpc.go` | Discord gateway communication and RPC logic | | `rpc.go` | Discord gateway communication and RPC logic |
| `pdk.gen.go` | Generated types from XTP schemas (combined) | | `pdk.gen.go` | Generated types from XTP schemas (combined) |
| `nd_host_*.go` | Host function wrappers (copied from `plugins/host/go/`) | | `nd_host_*.go` | Host function wrappers (copied from `plugins/host/go/`) |
## Host Services Used ## Host Services Used
| Service | Purpose | | Service | Purpose |
|---------|---------| |-----------|------------------------------------------------------------------|
| Cache | Store Discord sequence numbers and processed image URLs | | Cache | Store Discord sequence numbers and processed image URLs |
| Scheduler | Schedule heartbeats (recurring) and activity clearing (one-time) | | Scheduler | Schedule heartbeats (recurring) and activity clearing (one-time) |
| WebSocket | Maintain persistent connection to Discord gateway | | WebSocket | Maintain persistent connection to Discord gateway |
| Artwork | Get track artwork URLs for rich presence display | | Artwork | Get track artwork URLs for rich presence display |
## Implementation Details ## Implementation Details

View File

@ -23,19 +23,20 @@ rustup target add wasm32-wasip1
# Build the plugin # Build the plugin
cargo build --target wasm32-wasip1 --release cargo build --target wasm32-wasip1 --release
# The output will be at target/wasm32-wasip1/release/library_inspector.wasm # Package as .ndp
zip -j library-inspector.ndp manifest.json target/wasm32-wasip1/release/library_inspector.wasm
``` ```
Or use the provided Makefile from the examples directory: Or use the provided Makefile from the examples directory:
```bash ```bash
cd plugins/examples cd plugins/examples
make library-inspector.wasm make library-inspector.ndp
``` ```
## Installation ## Installation
1. Copy the `.wasm` file to your Navidrome plugins folder 1. Copy the `.ndp` file to your Navidrome plugins folder
2. Enable plugins in your Navidrome configuration: 2. Enable plugins in your Navidrome configuration:
```toml ```toml
@ -50,11 +51,9 @@ Folder = "/path/to/plugins"
Configure the inspection interval in the Navidrome UI (Settings → Plugins → library-inspector): Configure the inspection interval in the Navidrome UI (Settings → Plugins → library-inspector):
```json | Key | Description | Default |
{ |--------|------------------------------------------|--------------|
"cron": "@every 5m" | `cron` | Cron expression for inspection interval | `@every 1m` |
}
```
### Cron Expression Examples ### Cron Expression Examples

View File

@ -8,12 +8,19 @@ This is a minimal example demonstrating how to create a Navidrome plugin using G
2. Build the plugin: 2. Build the plugin:
```bash ```bash
go mod tidy go mod tidy
tinygo build -o minimal.wasm -target wasip1 -buildmode=c-shared ./main.go tinygo build -o plugin.wasm -target wasip1 -buildmode=c-shared ./main.go
zip -j minimal.ndp manifest.json plugin.wasm
```
Or using the examples Makefile:
```bash
cd plugins/examples
make minimal.ndp
``` ```
## Installing ## Installing
Copy `minimal.wasm` to your Navidrome plugins folder (default: `<data-folder>/plugins/`). Copy `minimal.ndp` to your Navidrome plugins folder (default: `<data-folder>/plugins/`).
## Configuration ## Configuration
@ -29,7 +36,7 @@ Agents = "lastfm,spotify,minimal"
## What This Example Demonstrates ## What This Example Demonstrates
- Exporting the required `nd_manifest` function - Plugin package structure (`.ndp` = zip with `manifest.json` + `plugin.wasm`)
- Implementing `nd_get_artist_biography` as a MetadataAgent capability - Implementing `nd_get_artist_biography` as a MetadataAgent capability
- Basic JSON input/output handling with the Extism PDK - Basic JSON input/output handling with the Extism PDK

View File

@ -23,18 +23,19 @@ A Python example plugin that demonstrates the **Scheduler** and **SubsonicAPI**
From the `plugins/examples` directory: From the `plugins/examples` directory:
```bash ```bash
make nowplaying-py.wasm make nowplaying-py.ndp
``` ```
Or directly: Or directly:
```bash ```bash
extism-py plugin/__init__.py -o nowplaying-py.wasm extism-py plugin/__init__.py -o plugin.wasm
zip -j nowplaying-py.ndp manifest.json plugin.wasm
``` ```
## Installation ## Installation
1. Copy `nowplaying-py.wasm` to your Navidrome plugins folder 1. Copy `nowplaying-py.ndp` to your Navidrome plugins folder
2. Enable plugins in `navidrome.toml`: 2. Enable plugins in `navidrome.toml`:
```toml ```toml
@ -43,20 +44,14 @@ extism-py plugin/__init__.py -o nowplaying-py.wasm
Folder = "/path/to/plugins" Folder = "/path/to/plugins"
``` ```
3. Configure the plugin in the UI (Settings → Plugins → nowplaying-py): 3. Configure the plugin in the UI (Settings → Plugins → nowplaying-py)
```json
{
"cron": "*/1 * * * *",
"user": "admin"
}
```
### Configuration Options ## Configuration
| Key | Description | Default | | Key | Description | Default |
|--------|-------------------------------------|------------------------------| |--------|-------------------------------------|---------------|
| `cron` | Cron expression for check frequency | `*/1 * * * *` (every minute) | | `cron` | Cron expression for check frequency | `*/1 * * * *` |
| `user` | Navidrome user for SubsonicAPI | `admin` | | `user` | Navidrome user for SubsonicAPI | `admin` |
## Testing ## Testing

View File

@ -20,7 +20,7 @@ A Navidrome plugin written in Rust that sends HTTP webhook notifications when tr
From the `plugins/examples` directory: From the `plugins/examples` directory:
```bash ```bash
make webhook-rs.wasm make webhook-rs.ndp
``` ```
Or build directly with cargo: Or build directly with cargo:
@ -28,28 +28,20 @@ Or build directly with cargo:
```bash ```bash
cd webhook-rs cd webhook-rs
cargo build --release cargo build --release
cp target/wasm32-unknown-unknown/release/webhook_rs.wasm ../webhook-rs.wasm zip -j webhook-rs.ndp manifest.json target/wasm32-unknown-unknown/release/webhook_rs.wasm
``` ```
## Installation ## Installation
Copy `webhook-rs.wasm` to your Navidrome plugins folder (configured via `Plugins.Folder` in your config). Copy `webhook-rs.ndp` to your Navidrome plugins folder (configured via `Plugins.Folder` in your config).
## Configuration ## Configuration
Configure in the Navidrome UI (Settings → Plugins → webhook-rs): Configure in the Navidrome UI (Settings → Plugins → webhook-rs):
```json | Key | Description | Example |
{ |--------|--------------------------------------|-----------------------------------------------------------|
"urls": "https://example.com/webhook,https://another.example.com/notify" | `urls` | Comma-separated list of webhook URLs | `https://example.com/hook1,https://example.com/hook2` |
}
```
### Configuration Options
| Key | Description | Example |
|--------|--------------------------------------|---------------------------------------------------------|
| `urls` | Comma-separated list of webhook URLs | `"https://example.com/hook1,https://example.com/hook2"` |
## Webhook Request Format ## Webhook Request Format

View File

@ -22,16 +22,11 @@ xtp plugin init \
## Building ## Building
### Using XTP CLI (recommended)
```bash
xtp plugin build
```
### Using TinyGo ### Using TinyGo
```bash ```bash
tinygo build -target wasip1 -buildmode=c-shared -o dist/plugin.wasm . tinygo build -target wasip1 -buildmode=c-shared -o plugin.wasm .
zip -j wikimedia.ndp manifest.json plugin.wasm
``` ```
### Using the Makefile ### Using the Makefile
@ -39,15 +34,22 @@ tinygo build -target wasip1 -buildmode=c-shared -o dist/plugin.wasm .
From the `plugins/examples` directory: From the `plugins/examples` directory:
```bash ```bash
make wikimedia.wasm make wikimedia.ndp
```
### Using XTP CLI
```bash
xtp plugin build
zip -j wikimedia.ndp manifest.json dist/plugin.wasm
``` ```
## Installation ## Installation
Copy the `.wasm` file to your Navidrome plugins folder: Copy the `.ndp` file to your Navidrome plugins folder:
```bash ```bash
cp dist/plugin.wasm /path/to/navidrome/plugins/wikimedia.wasm cp wikimedia.ndp /path/to/navidrome/plugins/
``` ```
Then enable plugins in your `navidrome.toml`: Then enable plugins in your `navidrome.toml`:
@ -73,23 +75,13 @@ brew install extism/tap/extism # macOS
# or see https://extism.org/docs/install for other platforms # or see https://extism.org/docs/install for other platforms
``` ```
Run these commands from the `plugins/examples` directory. Extract the wasm file from the package and test:
### Test the manifest
```bash ```bash
extism call wikimedia.wasm nd_manifest --wasi # Extract wasm from package
``` unzip -p wikimedia.ndp plugin.wasm > wikimedia.wasm
Expected output: # Test artist URL lookup with MBID (The Beatles)
```json
{"name":"Wikimedia","author":"Navidrome","version":"1.0.0","description":"Fetches artist metadata from Wikidata, DBpedia and Wikipedia","website":"https://navidrome.org","permissions":{"http":{"reason":"Fetch metadata from Wikimedia APIs","allowedHosts":["query.wikidata.org","dbpedia.org","en.wikipedia.org"]}}}
```
### Test artist URL lookup
```bash
# With MBID (The Beatles)
extism call wikimedia.wasm nd_get_artist_url --wasi \ extism call wikimedia.wasm nd_get_artist_url --wasi \
--input '{"id":"1","name":"The Beatles","mbid":"b10bbbfc-cf9e-42e0-be17-e2c3e1d2600d"}' \ --input '{"id":"1","name":"The Beatles","mbid":"b10bbbfc-cf9e-42e0-be17-e2c3e1d2600d"}' \
--allow-host "query.wikidata.org" --allow-host "query.wikidata.org"