docs(plugins): document the Storage host service

The README is the plugin author reference and every other host service has a
section there, but Storage had none, so the /storage guest path contract only
existed in code.

Documents the mount point and its backing directory, the manifest permission,
the host function, and the two behaviours an author would otherwise discover
the hard way: there is no size limit, and the directory outlives an uninstall.
This commit is contained in:
Deluan 2026-08-03 13:31:00 -04:00
parent 8a972eb462
commit fc6b1ae45a

View File

@ -30,6 +30,7 @@ The plugin system is built on **[Extism](https://extism.org/)**, a cross-languag
- [Scheduler](#scheduler)
- [Cache](#cache)
- [KVStore](#kvstore)
- [Storage](#storage)
- [Task](#task)
- [WebSocket](#websocket)
- [Library](#library)
@ -548,6 +549,52 @@ usage, err := host.KVStoreGetStorageUsed()
fmt.Printf("Using %d bytes\n", usage)
```
### Storage
A private read-write directory, mounted into the sandbox at `/storage` and backed by `${DataFolder}/plugins/${pluginID}/storage`. Survives server restarts. Use it for data that doesn't fit a key-value store: caches, downloaded files, generated indexes.
**Manifest permission:**
```json
{
"permissions": {
"storage": {
"reason": "Cache generated playlists between restarts"
}
}
}
```
**Host functions:**
| Function | Parameters | Description |
|--------------------------|------------|------------------------------------|
| `storage_getstoragepath` | – | Get the guest path of the mount |
**Usage:**
Normal WASI filesystem calls work inside the mount, so use the `os` package directly:
```go
import (
"os"
"path/filepath"
"github.com/navidrome/navidrome/plugins/pdk/go/host"
)
// The path never changes, so read it once instead of per operation
var storageDir = host.StorageGetStoragePath() // "/storage"
err := os.WriteFile(filepath.Join(storageDir, "cache.json"), data, 0600)
content, err := os.ReadFile(filepath.Join(storageDir, "cache.json"))
entries, err := os.ReadDir(storageDir)
```
> **Security:** The mount is confined to your plugin's own directory. Paths that would resolve outside it are rejected, and plugins cannot create symlinks inside the mount.
> **Note:** There is no size limit, unlike [KVStore](#kvstore). The directory is not deleted when a plugin is uninstalled.
### Task
Background task queue with retry support. Plugins enqueue tasks and process them by exporting the [`nd_task_execute`](#taskworker) capability function.