feat(plugins): punktfunk-host plugins CLI — add/remove/list/enable/disable/status
One-liner plugin management replacing the manual scripting-dir + bunfig + bun-add ritual: package ops forward to the bun runner (new sdk plugins module + runner-cli subcommands, 11 tests green), enable/disable/status drive the systemd unit on Linux and the PunktfunkScripting scheduled task on Windows (installer support in the ISS). Docs page rewritten as .mdx with per-platform Tabs (registered in mdx.tsx). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -149,7 +149,8 @@ directory of scripts and installed plugins as one service: crash-restarts with b
|
||||
for the five-line quickstart and unit templates.
|
||||
|
||||
For ready-made plugins — sync your ROM collection or your Playnite library into the game library,
|
||||
with a console page to manage them — see [Plugins](/docs/plugins).
|
||||
with a console page to manage them — see [Plugins](/docs/plugins). Installing one is two commands:
|
||||
`punktfunk-host plugins add <name>`, then `punktfunk-host plugins enable`.
|
||||
|
||||
The canonical "decide, don't just observe" pattern — approve pairing from your phone: watch
|
||||
`pairing.pending`, send yourself a notification, and call
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
---
|
||||
title: Plugins
|
||||
description: First-party plugins that sync your ROM collection or your Playnite library into the game library — and how to install them.
|
||||
---
|
||||
|
||||
Plugins extend the host through the **scripting runner** (see [Events & hooks](/docs/automation)). A
|
||||
plugin runs alongside the host, reconciles titles into your **game library** as a provider — so they
|
||||
appear in the grid on every client — and can add its own page to the [web console](/docs/web-console).
|
||||
|
||||
Two first-party plugins today:
|
||||
|
||||
| Plugin | What it does |
|
||||
|---|---|
|
||||
| **ROM Manager** | Scans your ROM directories, matches each platform to an installed emulator, and syncs them into the library with box art. |
|
||||
| **Playnite** | Mirrors your [Playnite](https://playnite.link) library — every store and emulator it manages — into the library, launched back through Playnite. |
|
||||
|
||||
## Installing a plugin
|
||||
|
||||
Plugins install as packages into the runner's plugins directory, and the runner
|
||||
(`punktfunk-scripting`) supervises them. It's a one-time registry setup, then `bun add`:
|
||||
|
||||
```sh
|
||||
# The runner's plugins directory:
|
||||
# Linux ~/.config/punktfunk/plugins
|
||||
# Windows %ProgramData%\punktfunk\plugins
|
||||
cd ~/.config/punktfunk/plugins # create it if it doesn't exist yet
|
||||
|
||||
# Point the @punktfunk scope at the registry (once):
|
||||
cat > bunfig.toml <<'EOF'
|
||||
[install.scopes]
|
||||
"@punktfunk" = "https://git.unom.io/api/packages/unom/npm/"
|
||||
EOF
|
||||
|
||||
bun add @punktfunk/plugin-rom-manager # or @punktfunk/plugin-playnite
|
||||
```
|
||||
|
||||
Then enable the runner — it's opt-in, off until you turn it on:
|
||||
|
||||
```sh
|
||||
systemctl --user enable --now punktfunk-scripting # Linux
|
||||
Enable-ScheduledTask PunktfunkScripting # Windows
|
||||
```
|
||||
|
||||
Open the [web console](/docs/web-console) and the plugin's page appears in the nav automatically —
|
||||
that's the whole install. Each plugin is also fully configurable from a `config.json` for headless
|
||||
hosts (see its README).
|
||||
|
||||
> Plugins are operator-installed code that runs as the host user — they can launch games and run
|
||||
> commands. Install only plugins you trust, from a registry you control.
|
||||
|
||||
## ROM Manager
|
||||
|
||||
`@punktfunk/plugin-rom-manager` — point it at your ROM directories and it scans them, matches each
|
||||
platform to an installed emulator, fetches box art (SteamGridDB, or the keyless libretro thumbnails),
|
||||
and reconciles the result into your library as the `rom-manager` provider. ~25 built-in platforms
|
||||
(NES through Switch, PS1/2/PSP, Dreamcast, and more), per-game overrides, and a console page to
|
||||
configure it all.
|
||||
|
||||
Install it as [above](#installing-a-plugin), then add a root or two — from the console's **ROM
|
||||
Manager** page, or in `~/.config/punktfunk/rom-manager/config.json`:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"roots": [
|
||||
{ "dir": "/mnt/roms/snes", "platform": "snes" },
|
||||
{ "dir": "/mnt/roms/ps1", "platform": "ps1", "excludes": ["*.sav"] }
|
||||
],
|
||||
"art": { "provider": "auto", "steamGridDbKey": "" }
|
||||
}
|
||||
```
|
||||
|
||||
Full options and the platform/emulator list are in
|
||||
[the plugin's repo](https://git.unom.io/unom/punktfunk-plugin-rom-manager).
|
||||
|
||||
## Playnite
|
||||
|
||||
`@punktfunk/plugin-playnite` — mirrors your **[Playnite](https://playnite.link)** library (Steam,
|
||||
GOG, Epic, Xbox, itch, emulators, manually-added games — everything Playnite manages) into your
|
||||
library. Launching a title hands it back to Playnite, which performs the real launch, so there are no
|
||||
per-store launch commands to maintain. Covers are served by the host, so it scales to large libraries.
|
||||
|
||||
Because Playnite keeps its library locked while running, this plugin has **two parts**, both on the
|
||||
Windows host:
|
||||
|
||||
1. **The plugin** (on the host) — install `@punktfunk/plugin-playnite` exactly as
|
||||
[above](#installing-a-plugin).
|
||||
2. **The Punktfunk Sync extension** (in Playnite) — download `punktfunk-sync.pext` from the
|
||||
[plugin's builds](https://git.unom.io/unom/punktfunk-plugin-playnite/actions) and **double-click
|
||||
it** to install it in Playnite like any add-on, then restart Playnite once.
|
||||
|
||||
Open the console's **Playnite** page — it shows "Exporter connected", and your games sync within
|
||||
seconds of any library change. Filters (installed-only, per-store, hidden) live on that page or in
|
||||
`~/.config/punktfunk/playnite/config.json`. Details are in
|
||||
[the plugin's repo](https://git.unom.io/unom/punktfunk-plugin-playnite).
|
||||
|
||||
## Writing your own
|
||||
|
||||
A plugin is a small TypeScript module built on `@punktfunk/host` (`definePlugin`), supervised by the
|
||||
runner. Start from the [SDK README](https://git.unom.io/unom/punktfunk/src/branch/main/sdk) — or the
|
||||
two plugins above, which are worked examples of the same shape.
|
||||
@@ -0,0 +1,185 @@
|
||||
---
|
||||
title: Plugins
|
||||
description: First-party plugins that sync your ROM collection or your Playnite library into the game library — and how to install them.
|
||||
---
|
||||
|
||||
Plugins extend the host through the **scripting runner** (see [Events & hooks](/docs/automation)). A
|
||||
plugin runs alongside the host, reconciles titles into your **game library** as a provider — so they
|
||||
appear in the grid on every client — and can add its own page to the [web console](/docs/web-console).
|
||||
|
||||
Two first-party plugins today:
|
||||
|
||||
| Plugin | What it does |
|
||||
|---|---|
|
||||
| **ROM Manager** | Scans your ROM directories, matches each platform to an installed emulator, and syncs them into the library with box art. |
|
||||
| **Playnite** | Mirrors your [Playnite](https://playnite.link) library — every store and emulator it manages — into the library, launched back through Playnite. |
|
||||
|
||||
## Installing a plugin
|
||||
|
||||
Two commands: install the plugin, then turn the runner on. The host CLI handles the rest — creating
|
||||
the plugins directory, pointing it at the package registry, and starting the supervisor.
|
||||
|
||||
<Tabs items={['Linux', 'Windows']}>
|
||||
<Tab value="Linux">
|
||||
|
||||
```sh
|
||||
punktfunk-host plugins add playnite # or: rom-manager
|
||||
punktfunk-host plugins enable # turn the runner on (once)
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab value="Windows">
|
||||
|
||||
Run these from an **elevated** PowerShell — right-click **PowerShell** → **Run as administrator**.
|
||||
The plugins directory lives under `%ProgramData%\punktfunk`, which is admin-owned, and the runner
|
||||
task runs as SYSTEM.
|
||||
|
||||
```powershell
|
||||
punktfunk-host plugins add playnite # or: rom-manager
|
||||
punktfunk-host plugins enable # turn the runner on (once)
|
||||
```
|
||||
|
||||
If `punktfunk-host` isn't found, open a **new** terminal (the installer adds it to `PATH`), or use
|
||||
the full path: `& "$env:ProgramFiles\punktfunk\punktfunk-host.exe" plugins add playnite`.
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
Open the [web console](/docs/web-console) and the plugin's page appears in the nav automatically —
|
||||
that's the whole install.
|
||||
|
||||
The runner is **opt-in**: `plugins add` installs, `plugins enable` turns it on. You only need
|
||||
`enable` once — plugins you add later are picked up automatically.
|
||||
|
||||
### The rest of the commands
|
||||
|
||||
| Command | What it does |
|
||||
|---|---|
|
||||
| `punktfunk-host plugins add <name…>` | Install one or more plugins. |
|
||||
| `punktfunk-host plugins remove <name…>` | Uninstall. |
|
||||
| `punktfunk-host plugins list` | List what's installed, with versions. |
|
||||
| `punktfunk-host plugins enable` | Enable + start the runner. |
|
||||
| `punktfunk-host plugins disable` | Stop + disable the runner. |
|
||||
| `punktfunk-host plugins status` | Is the runner enabled and running? |
|
||||
|
||||
A bare name resolves to the first-party package — `playnite` installs `@punktfunk/plugin-playnite`.
|
||||
A scoped (`@scope/pkg`) or `punktfunk-plugin-*` name is used verbatim, so third-party plugins work
|
||||
the same way.
|
||||
|
||||
> Plugins are operator-installed code that runs as the host user — they can launch games and run
|
||||
> commands. Install only plugins you trust, from a registry you control.
|
||||
|
||||
## ROM Manager
|
||||
|
||||
`@punktfunk/plugin-rom-manager` — point it at your ROM directories and it scans them, matches each
|
||||
platform to an installed emulator, fetches box art (SteamGridDB, or the keyless libretro thumbnails),
|
||||
and reconciles the result into your library as the `rom-manager` provider. ~25 built-in platforms
|
||||
(NES through Switch, PS1/2/PSP, Dreamcast, and more), per-game overrides, and a console page to
|
||||
configure it all.
|
||||
|
||||
```sh
|
||||
punktfunk-host plugins add rom-manager
|
||||
```
|
||||
|
||||
Then add a root or two — from the console's **ROM Manager** page, or in the config file:
|
||||
|
||||
<Tabs items={['Linux', 'Windows']}>
|
||||
<Tab value="Linux">
|
||||
|
||||
`~/.config/punktfunk/rom-manager/config.json`:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"roots": [
|
||||
{ "dir": "/mnt/roms/snes", "platform": "snes" },
|
||||
{ "dir": "/mnt/roms/ps1", "platform": "ps1", "excludes": ["*.sav"] }
|
||||
],
|
||||
"art": { "provider": "auto", "steamGridDbKey": "" }
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab value="Windows">
|
||||
|
||||
`%ProgramData%\punktfunk\rom-manager\config.json`:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"roots": [
|
||||
{ "dir": "D:\\roms\\snes", "platform": "snes" },
|
||||
{ "dir": "D:\\roms\\ps1", "platform": "ps1", "excludes": ["*.sav"] }
|
||||
],
|
||||
"art": { "provider": "auto", "steamGridDbKey": "" }
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
Full options and the platform/emulator list are in
|
||||
[the plugin's repo](https://git.unom.io/unom/punktfunk-plugin-rom-manager).
|
||||
|
||||
## Playnite
|
||||
|
||||
`@punktfunk/plugin-playnite` — mirrors your **[Playnite](https://playnite.link)** library (Steam,
|
||||
GOG, Epic, Xbox, itch, emulators, manually-added games — everything Playnite manages) into your
|
||||
library. Launching a title hands it back to Playnite, which performs the real launch, so there are no
|
||||
per-store launch commands to maintain. Covers are served by the host, so it scales to large libraries.
|
||||
|
||||
Playnite is Windows-only, so both halves of this one live on the **Windows host**. Because Playnite
|
||||
keeps its library locked while running, there are **two parts**:
|
||||
|
||||
1. **The plugin** — from an elevated PowerShell:
|
||||
|
||||
```powershell
|
||||
punktfunk-host plugins add playnite
|
||||
punktfunk-host plugins enable
|
||||
```
|
||||
|
||||
2. **The Punktfunk Sync extension** (in Playnite) — download `punktfunk-sync.pext` from the
|
||||
[plugin's builds](https://git.unom.io/unom/punktfunk-plugin-playnite/actions) and **double-click
|
||||
it** to install it in Playnite like any add-on, then restart Playnite once.
|
||||
|
||||
Open the console's **Playnite** page — it shows "Exporter connected", and your games sync within
|
||||
seconds of any library change. Filters (installed-only, per-store, hidden) live on that page or in
|
||||
`%ProgramData%\punktfunk\playnite\config.json`. Details are in
|
||||
[the plugin's repo](https://git.unom.io/unom/punktfunk-plugin-playnite).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**`punktfunk-host: command not found`** — on Windows, open a new terminal so it picks up the
|
||||
installer's `PATH` change, or call the exe by full path. On Linux the host package installs it to
|
||||
`/usr/bin/punktfunk-host`.
|
||||
|
||||
**"the plugin runner isn't installed"** — the runner ships as its own package. On Debian/Ubuntu:
|
||||
`sudo apt install punktfunk-scripting`. On Windows, re-run the installer and keep the scripting
|
||||
component.
|
||||
|
||||
**The plugin doesn't show up in the console** — check the runner is actually running with
|
||||
`punktfunk-host plugins status`, then look at its log:
|
||||
|
||||
<Tabs items={['Linux', 'Windows']}>
|
||||
<Tab value="Linux">
|
||||
|
||||
```sh
|
||||
journalctl --user -u punktfunk-scripting -f
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab value="Windows">
|
||||
|
||||
The runner task doesn't write a log file, so run it in the foreground to watch it start your
|
||||
plugins (stop it with <kbd>Ctrl</kbd>+<kbd>C</kbd>):
|
||||
|
||||
```powershell
|
||||
& "$env:ProgramFiles\punktfunk\bun\bun.exe" "$env:ProgramFiles\punktfunk\scripting\runner-cli.js"
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Writing your own
|
||||
|
||||
A plugin is a small TypeScript module built on `@punktfunk/host` (`definePlugin`), supervised by the
|
||||
runner. Start from the [SDK README](https://git.unom.io/unom/punktfunk/src/branch/main/sdk) — or the
|
||||
two plugins above, which are worked examples of the same shape.
|
||||
Reference in New Issue
Block a user