Seventh plugin out, and the first that was already dead. Soulseek had been switched off since 2026-08-13: hono.ts had the router import and its mount commented out, so createSidecarProxy never ran, registerProxiedPrefix was never called, the slskd:server announcement fired into a void, and officer-slskd was not in the ecosystem at all. The permission entry had been reduced to api: [], which is why assertPermissionTotality was satisfied and the server booted clean. The UI rendered perfectly and every request 404'd. So this is a resurrection as well as a move. The mount is now /api/soulseek, derived via mountPrefix from the appName — all 47 frontend call sites repointed from /slskd/. The credential key in service_connections stays 'slskd': it names the daemon, not the route. Those two strings differ on purpose and conflating them reads the wrong row. The connection stays in core service_connections, as transmission does, so 'slskd' remains in a platform union this plugin cannot extend. Recorded in PLUGIN.md. Unlike transmission this plugin does own a schema: favourites and the two halves of the cached browse tree, which slskd has no concept of. Those three tables had been dropped from the drizzle barrel, so bun db:push would have deleted them on any server holding data. 313 palette classes converted to the semantic tone set, including a shared PHASE_TONE the three transfer views previously each copied.
39 lines
1.5 KiB
Markdown
39 lines
1.5 KiB
Markdown
# Soulseek
|
|
|
|
Search and download from the Soulseek network, through your own [slskd](https://github.com/slskd/slskd)
|
|
daemon — inside Officer, with the API key held server-side so no device ever carries it.
|
|
|
|
## What you get
|
|
|
|
- **Search** the network, with results grouped by peer and filterable by bitrate, size and free slots
|
|
- **Transfers** — downloads and uploads, with queue position, retry and cancel
|
|
- **Browse a peer's shares** as a tree, cached locally so it survives them going offline
|
|
- **Favourites** — peers worth coming back to
|
|
- **Rooms and chat**, joined and available
|
|
- **Server status** — connect, disconnect and see what the daemon is doing
|
|
|
|
Favourites and the cached browse tree are Officer's own: slskd has no concept of either.
|
|
|
|
## Requirements
|
|
|
|
A running slskd instance Officer can reach, and its API key.
|
|
|
|
## Setup
|
|
|
|
Install the plugin, open **/soulseek**, and fill in the connection panel — the daemon URL and the API
|
|
key. The key is encrypted at rest and never sent to the browser.
|
|
|
|
The plugin does **not** install or supervise slskd. Point it at one you already run.
|
|
|
|
## Permissions
|
|
|
|
One permission, `soulseek`, grantable per role like any other app permission. It gates the whole
|
|
surface.
|
|
|
|
## Notes
|
|
|
|
- The connection is stored per-owner in the platform's `service_connections` table under the service
|
|
name **`slskd`**, while the HTTP mount is **`/api/soulseek`**. Those two strings differ on purpose —
|
|
see `PLUGIN.md`.
|
|
- Live search results arrive by polling; the SignalR hub is not proxied.
|