Welcome to the community, @mochan - and what an entrance! This is a seriously impressive first plugin.
I have had a good look through the code and want to share some feedback. The overall quality here is well above what we typically see, so please take the issues below in the spirit they are intended - this is already close to being ready, and addressing these will get it over the line.
What you got right
Before the issues list, I want to call out the things that are genuinely well done here, because there is a lot to like.
The layered architecture (api-client ā parser ā service ā adapter) with clean separation of concerns is textbook good engineering. Each layer is independently testable, and you have actually tested them - eight test files covering parsers, the API client with proper HTTP mocking, the service facade, and the Volumio adapter. That is more test coverage than most plugins in the store have.
The TypeScript is strict-mode with noUncheckedIndexedAccess, proper null handling throughout, separate raw API types versus domain types, and a thoughtful error hierarchy with PlexApiError ā PlexAuthError / PlexConnectionError including proper error chaining via cause. The URI encoding scheme for Plex keys (slash to double-underscore) is a practical solution applied consistently. And delegating playback to MPD via consume mode is exactly the right pattern for a Volumio music service.
The development tooling (explore.ts, play.ts, plex-browse.ts) shows a mature workflow. Being able to validate stream URLs independently of Volumio via ffplay is a smart approach.
So - well done. Now for the things that need attention.
Must fix before submission
1. The dist/ directory is missing from the archive. The index.js entry point does require('./dist/index.js') but there is no dist/ folder in the zip. The install.sh only runs npm install --production, which will not compile TypeScript. Without dist/, the plugin will crash immediately on enable. Either include the pre-built dist/ in your release archive, or rethink the build pipeline. Compiling on-device is not practical for ARM targets.
2. The MPD addid command may be wrong. In your _clearAddPlayTrack method you send sendMpdCommand("addid", [track.uri]). Other music service plugins (YouTube Music, Spotify, etc.) use "add" for HTTP stream URLs. The addid command returns a song ID you are discarding, which suggests "add" was the intended command. Please test this against actual Volumio hardware - it may work on some MPD versions and fail on others.
3. Token field should be masked. Your UIConfig.json uses "type": "text" for the token input. Change this to "type": "password" so the Plex token is not displayed in cleartext on the settings page.
Should fix
4. N+1 API calls in explodeUri. When exploding an album or playlist, you first fetch all tracks, then call getPlayableTrack individually for each one. Each of those makes a separate HTTP request to re-fetch metadata you already have. For a 20-track album that is 21 requests when 1 would do. The track objects from getAlbumTracks already contain the streamKey you need - just build the stream URL directly from that using buildStreamUrl.
5. Browse-back from album tracks goes to root. Your browseAlbum method sets prev: { uri: "plex" }, which sends the user back to the Plex root menu instead of back to the albums list or the artist they came from. Compare with browsePlaylist which correctly sets prev to "plex/playlists". At minimum, set it to "plex/albums".
6. No HTTPS support. The api-client hardcodes the http module and stream-resolver hardcodes http:// in URLs. Many Plex servers use HTTPS. If supporting HTTPS is not in scope for v1, please document this clearly - especially since auth tokens are being sent in the clear.
7. Unused modules. PlaybackController, PlaylistManager, and UIStateManager are fully implemented and tested but never actually used - the adapter delegates everything to MPD, which is correct. Either remove these or add a note explaining they are scaffolding for future use. They add review overhead as-is.
Nice to have
8. Large library performance. getAllArtists and getAllAlbums fetch everything across all libraries in one go. For users with thousands of albums this will be slow. Plex supports pagination via X-Plex-Container-Start and X-Plex-Container-Size - worth considering for a future release.
9. Package.json gaps. The author field is empty, there is no LICENSE file despite the ISC declaration, no repository field, and no engines field specifying Node compatibility.
10. Token appears in logs. Your logger calls include full URIs which will contain the Plex token in stream URLs. Consider masking tokens in log output.
11. scripts/ directory. The development scripts have no purpose on a deployed Volumio device - exclude them from the install package.
12. Default host. localhost as the default host only works if Plex runs on the same device as Volumio, which is rare. A blank default with clear guidance would be more user-friendly.
Summary
This is strong work. The architecture is clean, the code is well-typed, the tests are thorough, and the Volumio integration patterns are correct. The critical blocker is just the missing dist/ directory - fix that plus the MPD command and the token masking, and you have a solid v1 ready for the store.
Looking forward to seeing this progress. The Plex user base in this community is not small, and having proper playlist support (which DLNA lacks, as you noted) fills a real gap.
Kind Regards,