* test(artwork): add benchmark helpers for generating test images
* test(artwork): add image decode benchmarks for JPEG/PNG at various sizes
* test(artwork): add image resize benchmarks for Lanczos at various sizes
* test(artwork): add image encode benchmarks for JPEG quality levels and PNG
* test(artwork): add full resize pipeline benchmark (decode+resize+encode)
* test(artwork): add tag extraction benchmark for embedded art
* test(cache): add file cache benchmarks for read, write, and concurrent access
* test(artwork): add E2E benchmarks for artwork.Get with cache on/off and concurrency
* fix(test): use absolute path for tag extraction benchmark fixture
* test(artwork): add resize alternatives benchmark comparing resamplers
* perf(artwork): switch to CatmullRom resampler and JPEG for square images
Replace imaging.Lanczos with imaging.CatmullRom for image resizing
(30% faster, indistinguishable quality at thumbnail sizes). Stop forcing
PNG encoding for square images when the source is JPEG — JPEG is smaller
and faster to encode. Square images from JPEG sources went from 52ms to
10ms (80% improvement). Add sync.Pool for encode buffers to reduce GC
pressure under concurrent load.
* perf(artwork): increase cache warmer concurrency from 2 to 4 workers
Resize is CPU-bound, so more workers improve throughput on multi-core
systems. Doubled worker count to better utilize available cores during
background cache warming.
* perf(artwork): switch to xdraw.ApproxBiLinear and always encode as JPEG
Replace disintegration/imaging with golang.org/x/image/draw for image
resizing. This eliminates ~92K allocations per resize (from imaging's
internal goroutine parallelism) down to ~20, reducing GC pressure under
concurrent load.
Always encode resized artwork as JPEG regardless of source format, since
cover art doesn't need transparency. This is ~5x faster than PNG encode
and produces much smaller output (e.g. 18KB JPEG vs 124KB PNG).
* perf(artwork): skip external API call when artist image URL is cached
ArtistImage() was always calling the external agent (Spotify/Last.fm)
to get the image URL, even when the artist already had URLs stored in
the database. This caused every artist image request to block on an
external API call, creating severe serialization when loading artist
grids (5-20 seconds for the first page).
Now use the stored URL directly when available. Artists with no stored
URL still fetch synchronously. Background refresh via UpdateArtistInfo
handles TTL-based URL updates.
* perf(artwork): increase getCoverArt throttle from NumCPU/3 to NumCPU
The previous default of max(2, NumCPU/3) was too aggressive for artist
images which are I/O-bound (downloading from external CDNs), not
CPU-bound. On an 8-core machine this meant only 2 concurrent requests,
causing a staircase pattern where 12 images took ~2.4s wall-clock.
Bumping to max(4, NumCPU) cuts wall-clock time by ~50% for artist image
grids while still preventing unbounded concurrency for CPU-bound resizes.
* perf(artwork): encode resized images as WebP instead of JPEG
Switch from JPEG to WebP encoding for resized artwork using gen2brain/webp
(libwebp via WASM, no CGo). WebP produces ~74% smaller output at the same
quality with only ~25% slower full-pipeline encode time (cached, so only
paid once per artwork+size).
Use NRGBA image type to preserve alpha channel in WebP output, and
transparent padding for square canvas instead of black.
Also removes the disintegration/imaging dependency entirely by replacing
imaging.Fill in playlist tile generation with a custom fillCenter function
using xdraw.ApproxBiLinear.
* perf(artwork): switch from ApproxBiLinear to BiLinear scaling for improved image processing
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(configuration): rename CoverJpegQuality to CoverArtQuality and update references
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(artwork): add DevJpegCoverArt option to control JPEG encoding for cover art
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(artwork): remove redundant transparent fill and handle encode errors in resizeImage
Removed a no-op draw.Draw call that filled the NRGBA canvas with
transparent pixels — NewNRGBA already zero-initializes to fully
transparent. Also added an early return on encode failure to avoid
allocating and copying potentially corrupt buffer data before returning
the error.
* fix(configuration): reorder default agents (deezer is faster)
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(test): resolve dogsled lint warning in tag extraction benchmark
Use all return values from runtime.Caller instead of discarding three
with blank identifiers, which triggered the dogsled linter.
* fix(artwork): revert cache key format
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(configuration): remove deprecated CoverJpegQuality field and update references to CoverArtQuality
Signed-off-by: Deluan <deluan@navidrome.org>
---------
Signed-off-by: Deluan <deluan@navidrome.org>
Introduced a typed Claims struct in core/auth to replace the raw
map[string]any approach used for JWT claims throughout the codebase.
This provides compile-time safety and better readability when creating,
validating, and extracting JWT tokens. Also upgraded lestrrat-go/jwx
from v2 to v3 and go-chi/jwtauth to v5.4.0, adapting all callers to
the new API where token accessor methods now return tuples instead of
bare values. Updated all affected handlers, middleware, and tests.
Signed-off-by: Deluan <deluan@navidrome.org>
* chore(deps): update go-taglib fork with MKA/Matroska support
Bump deluan/go-taglib to cf75207bfff8, which upgrades the underlying
taglib to v2.2 and adds Matroska container format detection and
metadata handling (MKA audio files).
* chore(deps): update cross-taglib version to 2.2.0-1
Signed-off-by: Deluan <deluan@navidrome.org>
* chore(make): rename run-docker target to docker-run for consistency
Signed-off-by: Deluan <deluan@navidrome.org>
* chore(go-taglib): update version to 2.2 WASM and add debug logging
Signed-off-by: Deluan <deluan@navidrome.org>
* chore(deps): update go-taglib to v0.0.0-20260220032326 for MKA fixes
Signed-off-by: Deluan <deluan@navidrome.org>
---------
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: split reflex -R flags to preserve directory exclusion optimization
Combining the _test.go exclusion pattern (which uses $) into the same -R
regex as the directory prefixes (^ui, ^data, ^db/migrations) disabled
reflex's ExcludePrefix optimization. Reflex disables prefix-based
directory skipping when the regex AST contains $, \z, or \b operators,
causing it to traverse into ui/node_modules and hit "too many open files".
Splitting into two separate -R flags fixes this: the directory prefix
regex remains $-free so ExcludePrefix works, while the _test.go pattern
gets its own flag where the $ anchor doesn't affect directory skipping.
* fix(gotaglib): pass filename hint to OpenStream for format detection
OpenStream relies on content-sniffing when no filename is provided,
which fails for some files (e.g. OPUS). Pass the filename via the new
WithFilename option so TagLib can use the file extension as a hint.
Also adds an OPUS test fixture and test entry.
Relates to https://github.com/navidrome/navidrome/issues/4604#issuecomment-3868569113, #4998, #5010
* chore(plugins): remove the old plugins system implementation
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement new plugin system with using Extism
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add capability detection for plugins based on exported functions
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add auto-reload functionality for plugins with file watcher support
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add auto-reload functionality for plugins with file watcher support
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): standardize variable names and remove superfluous wrapper functions
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(plugins): improve error handling and logging in plugin manager
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): implement plugin function call helper and refactor MetadataAgent methods
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(plugins): race condition in plugin manager
* tests(plugins): change BeforeEach to BeforeAll in MetadataAgent tests
Signed-off-by: Deluan <deluan@navidrome.org>
* tests(plugins): optimize tests
Signed-off-by: Deluan <deluan@navidrome.org>
* tests(plugins): more optimizations
Signed-off-by: Deluan <deluan@navidrome.org>
* test(plugins): ignore goroutine leaks from notify library in tests
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add Wikimedia plugin for Navidrome to fetch artist metadata
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): enhance plugin logging and set User-Agent header
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement scrobbler plugin with authorization and scrobbling capabilities
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): integrate logs
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): clean up manifest struct and improve plugin loading logic
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add metadata agent and scrobbler schemas for bootstrapping plugins
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(hostgen): add hostgen tool for generating Extism host function wrappers
- Implemented hostgen tool to generate wrappers from annotated Go interfaces.
- Added command-line flags for input/output directories and package name.
- Introduced parsing and code generation logic for host services.
- Created test data for various service interfaces and expected generated code.
- Added documentation for host services and annotations for code generation.
- Implemented SubsonicAPI service with corresponding generated code.
* feat(subsonicapi): update Call method to return JSON string response
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement SubsonicAPI host function integration with permissions
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(generator): error-only methods in response handling
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): generate client wrappers for host functions
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(generator): remove error handling for response.Error in client templates
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(scheduler): add Scheduler service interface with host function wrappers for scheduling tasks
* feat(plugins): add WASI build constraints to client wrapper templates, to avoid lint errors
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(scheduler): implement Scheduler service with one-time and recurring scheduling capabilities
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(manifest): remove unused ConfigPermission from permissions schema
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(scheduler): add scheduler callback schema and implementation for plugins
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(scheduler): streamline scheduling logic and remove unused callback tracking
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(scheduler): add Close method for resource cleanup on plugin unload
Signed-off-by: Deluan <deluan@navidrome.org>
* docs(scheduler): clarify SchedulerCallback requirement for scheduling functions
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: update wasm build rule to include all Go files in the directory
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: rewrite the wikimedia plugin using the XTP CLI
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(scheduler): replace uuid with id.NewRandom for schedule ID generation
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: capabilities registration
Signed-off-by: Deluan <deluan@navidrome.org>
* test: add scheduler service isolation test for plugin instances
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: update plugin manager initialization and encapsulate logic
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add WebSocket service definitions for plugin communication
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: implement WebSocket service for plugin integration and connection management
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add Crypto Ticker example plugin for real-time cryptocurrency price updates via Coinbase WebSocket API
Also add the lifecycle capability
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: use context.Background() in invokeCallback for scheduled tasks
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: rename plugin.create() to plugin.instance()
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: rename pluginInstance to plugin for consistency across the codebase
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: simplify schedule cloning in Close method and enhance plugin cleanup error handling
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: implement Artwork service for generating artwork URLs in Navidrome plugins - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: moved public URL builders to avoid import cycles
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add Cache service for in-memory TTL-based caching in plugins
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add Discord Rich Presence example plugin for Navidrome integration
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: host function wrappers to use structured request and response types
- Updated the host function signatures in `nd_host_artwork.go`, `nd_host_scheduler.go`, `nd_host_subsonicapi.go`, and `nd_host_websocket.go` to accept a single parameter for JSON requests.
- Introduced structured request and response types for various cache operations in `nd_host_cache.go`.
- Modified cache functions to marshal requests to JSON and unmarshal responses, improving error handling and code clarity.
- Removed redundant memory allocation for string parameters in favor of JSON marshaling.
- Enhanced error handling in WebSocket and cache operations to return structured error responses.
* refactor: error handling in various plugins to convert response.Error to Go errors
- Updated error handling in `nd_host_scheduler.go`, `nd_host_websocket.go`, `nd_host_artwork.go`, `nd_host_cache.go`, and `nd_host_subsonicapi.go` to convert string errors from responses into Go errors.
- Removed redundant error checks in test data plugins for cleaner code.
- Ensured consistent error handling across all plugins to improve reliability and maintainability.
* refactor: rename fake plugins to test plugins for clarity in integration tests
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add help target to Makefile for plugin usage instructions
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add Cover Art Archive plugin as an example of Python plugin
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: update Makefile and README to clarify Go plugin usage
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: include plugin capabilities in loading log message
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add trace logging for plugin availability and error handling in agents
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add Now Playing Logger plugin to showcase calling host functions from Python plugins
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: generate Python client wrappers for various host services
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add generated host function wrappers for Scheduler and SubsonicAPI services
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: update Python plugin documentation and usage instructions for host function wrappers
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add Webhook Scrobbler plugin in Rust to send HTTP notifications on scrobble events
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: enable parallel loading of plugins during startup
Signed-off-by: Deluan <deluan@navidrome.org>
* docs: update README to include WebSocket callback schema in plugin documentation
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: extend plugin watcher with improved logging and debounce duration adjustment
Signed-off-by: Deluan <deluan@navidrome.org>
* add trace message for plugin recompiles
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: implement plugin cache purging functionality
Signed-off-by: Deluan <deluan@navidrome.org>
* test: move purgeCacheBySize unit tests
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins UI): add plugin repository and database support
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins UI): add plugin management routes and middleware
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins UI): implement plugin synchronization with database for add, update, and remove actions
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins UI): add PluginList and PluginShow components with plugin management functionality
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): optimize plugin change detection
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins UI): improve PluginList structure
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins UI): enhance PluginShow with author, website, and permissions display
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins UI): refactor to use MUI and RA components
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins UI): add error handling for plugin enable/disable actions
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): inject PluginManager into native API
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): update GetManager to accept DataStore parameter
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add subsonicRouter to Manager and refactor host service registration
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): enhance debug logging for plugin actions and recompile logic
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): break manager.go into smaller, focused files
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): streamline error handling and improve plugin retrieval logic
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): update newWebSocketService to use WebSocketPermission for allowed hosts
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): introduce ToggleEnabledSwitch for managing plugin enable/disable state
Signed-off-by: Deluan <deluan@navidrome.org>
* docs: update READMEs
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(library): add Library service for metadata access and filesystem integration
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add Library Inspector plugin for periodic library inspection and file size logging
Signed-off-by: Deluan <deluan@navidrome.org>
* docs: update README to reflect JSON configuration format for plugins
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(build): update target to wasm32-wasip1 for improved WASI support
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement configuration management UI with key-value pairs support
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(ui): adjust grid layout in InfoRow component for improved responsiveness
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): rename ErrorIndicator to EnabledOrErrorField and enhance error handling logic
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(i18n): add Portuguese translations for plugin management and notifications
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add support for .ndp plugin packages and update build process
Signed-off-by: Deluan <deluan@navidrome.org>
* docs: update README for .ndp plugin packaging and installation instructions
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement KVStore service for persistent key-value storage
Signed-off-by: Deluan <deluan@navidrome.org>
* docs: enhance README with Extism plugin development resources and recommendations
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): integrate event broker into plugin manager
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): update config handling in PluginShow to track last record state
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add Rust host function library and example implementation of Discord Rich Presence plugin in Rust
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): generate Rust lib.rs file to expose host function wrappers
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): update JSON field names to camelCase for consistency
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: reduce cyclomatic complexity by refactoring main function
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): enhance Rust code generation with typed struct support and improved type handling
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add Go client library with host function wrappers and documentation
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): generate Go client stubs for non-WASM platforms
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): update client template file names for consistency
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add initial implementation of the Navidrome Plugin Development Kit code generator - Pahse 1
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implementation of the Navidrome Plugin Development Kit with generated client wrappers and service interfaces - Phase 2
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implementation of the Navidrome Plugin Development Kit with generated client wrappers and service interfaces - Phase 2 (2)
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implementation of the Navidrome Plugin Development Kit with generated client wrappers and service interfaces - Phase 3
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implementation of the Navidrome Plugin Development Kit with generated client wrappers and service interfaces - Phase 4
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implementation of the Navidrome Plugin Development Kit with generated client wrappers and service interfaces - Phase 5
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): consistent naming/types across PDK
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): streamline plugin function signatures and error handling
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): update scrobbler interface to return errors directly instead of response structs
Signed-off-by: Deluan <deluan@navidrome.org>
* test: make all test plugins use the PDK
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): reorganize and sort type definitions for consistency
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): update error handling for methods to return errors directly
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): update function signatures to return values directly instead of response structs
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): update request/response types to use private naming conventions
Signed-off-by: Deluan <deluan@navidrome.org>
* build: mark .wasm files as intermediate for cleanup after building .ndp
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): consolidate PDK module path and update Go version to 1.25
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: implement Rust PDK
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): reorganize Rust output structure to follow standard conventions
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): update Discord Rich Presence and Library Inspector plugins to use nd-pdk for service calls and implement lifecycle management
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): update macro names for websocket and metadata registration to improve clarity and consistency
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): rename scheduler callback methods for consistency and clarity
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): update export wrappers to use `//go:wasmexport` for WebAssembly compatibility
Signed-off-by: Deluan <deluan@navidrome.org>
* docs: update plugin registration docs
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(plugins): generate host wrappers
Signed-off-by: Deluan <deluan@navidrome.org>
* test(plugins): conditionally run goleak checks based on CI environment
Signed-off-by: Deluan <deluan@navidrome.org>
* docs: update README to reflect changes in plugin import paths
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): update plugin instance creation to accept context for cancellation support
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(plugins): update return types in metadata interfaces to use pointers
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(plugins): enhance type handling for Rust and XTP output in capability generation
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(plugins): update IsAuthorized method to return boolean instead of response object
Signed-off-by: Deluan <deluan@navidrome.org>
* test(plugins): add unit tests for rustOutputType and isPrimitiveRustType functions
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement XTP JSONSchema validation for generated schemas
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(plugins): update response types in testMetadataAgent methods to use pointers
Signed-off-by: Deluan <deluan@navidrome.org>
* docs: update Go and Rust plugin developer sections for clarity
Signed-off-by: Deluan <deluan@navidrome.org>
* docs: correct example link for library inspector in README
Signed-off-by: Deluan <deluan@navidrome.org>
* docs: clarify artwork URL generation capabilities in service descriptions
Signed-off-by: Deluan <deluan@navidrome.org>
* docs: update README to include Rust PDK crate information for plugin developers
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: handle URL parsing errors and use atomic upsert in plugin repository
Added proper error handling for url.Parse calls in PublicURL and AbsoluteURL
functions. When parsing fails, PublicURL now falls back to AbsoluteURL, and
AbsoluteURL logs the error and returns an empty string, preventing malformed
URLs from being generated.
Replaced the non-atomic UPDATE-then-INSERT pattern in plugin repository Put
method with a single atomic INSERT ... ON CONFLICT statement. This eliminates
potential race conditions and improves consistency with the upsert pattern
already used in host_kvstore.go.
* feat: implement mock service instances for non-WASM builds using testify/mock
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: Discord RPC struct to encapsulate WebSocket logic
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add support for experimental WebAssembly threads
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add PDK abstraction layer with mock support for non-WASM builds
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add unit tests for Discord plugin and RPC functionality
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: update return types in minimalPlugin and wikimediaPlugin methods to use pointers
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: context cancellation and implement WebSocket callback timeout for improved error handling
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: conditionally include error handling in generated client code templates
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: implement ConfigService for plugin configuration management
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: enhance plugin manager to support metrics recording
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: make MockPDK private
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: update interface types to use 'any' in plugin repository methods
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: rename List method to Keys for clarity in configuration management
Signed-off-by: Deluan <deluan@navidrome.org>
* test: add ndpgen plugin tests in the pipeline and update Makefile
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add users permission management to plugin system
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: streamline users integration tests and enhance plugin user management
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: remove UserID from scrobbler request structure
Signed-off-by: Deluan <deluan@navidrome.org>
* test: add integration tests for UsersService enable gate behavior
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: implement user permissions for SubsonicAPI and scrobbler plugins
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: show proper error in the UI when enabling a plugin fails
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add library permission management to plugin system
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add user permission for processing scrobbles in Discord Rich Presence plugin
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: implement dynamic loading for buffered scrobbler plugins
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add GetAdmins method to retrieve admin users from the plugin
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: update Portuguese translations for user and library permissions
Signed-off-by: Deluan <deluan@navidrome.org>
* reorder migrations
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: remove unnecessary bulkActionButtons prop from PluginList component
* feat: add manual plugin rescan functionality and corresponding UI action
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: implement user/library and plugin management integration with cleanup on deletion
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: replace core mock services with test-specific implementations to avoid import cycles
* feat: add ID fields to Artist and Song structs and enhance track loading logic by prioritizing ID matches
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: update plugin permissions from allowedHosts to requiredHosts for better clarity and consistency
* feat: refactor plugin host permissions to use RequiredHosts directly for improved clarity
* fix: don't record metrics for plugin calls that aren't implemented at all
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: enhance connection management with improved error handling and cleanup logic
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: introduce ArtistRef struct for better artist representation and update track metadata handling
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: update user configuration handling to use user key prefix for improved clarity
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: enhance ConfigCard input fields with multiline support and vertical resizing
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: rust plugin compilation error
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: implement IsOptionPattern method for better return type handling in Rust PDK generation
Signed-off-by: Deluan <deluan@navidrome.org>
---------
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(reader): prioritize cover art selection by base filename without numeric suffixes
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(reader): update image file comparison to use natural sorting and prioritize files without numeric suffixes
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(reader): simplify comparison, add case-sensitivity test case
Signed-off-by: Deluan <deluan@navidrome.org>
---------
Signed-off-by: Deluan <deluan@navidrome.org>
* chore: update to Go 1.25.3
Signed-off-by: Deluan <deluan@navidrome.org>
* chore: update to golangci-lint
Signed-off-by: Deluan <deluan@navidrome.org>
* chore: update go dependencies
Signed-off-by: Deluan <deluan@navidrome.org>
* chore: update vite dependencies in package.json and improve EventSource mock in tests
- Upgraded @vitejs/plugin-react to version 5.1.0 and @vitest/coverage-v8 to version 4.0.3.
- Updated vite to version 7.1.12 and vite-plugin-pwa to version 1.1.0.
- Enhanced the EventSource mock implementation in eventStream.test.js for better test isolation.
* ci: remove coverage flag from Go test command in pipeline
* chore: update Node.js version to v24 in devcontainer, pipeline, and .nvmrc
* chore: prettier
Signed-off-by: Deluan <deluan@navidrome.org>
* chore: update actions/checkout from v4 to v5 in pipeline and update-translations workflows
* chore: update JS dependencies remove unused jest-dom import in Linkify.test.jsx
* chore: update actions/download-artifact from v4 to v5 in pipeline
---------
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add minimal test agent plugin with API definitions
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add plugin manager with auto-registration and unique agent names
Introduced a plugin manager that scans the plugins folder for subdirectories containing plugin.wasm files and auto-registers them as agents using the directory name as the unique agent name. Updated the configuration to support plugins with enabled/folder options, and ensured the plugin manager is started as a concurrent task during server startup. The wasmAgent now returns the plugin directory name for AgentName, ensuring each plugin agent is uniquely identifiable. This enables dynamic plugin discovery and integration with the agents orchestrator.
* test: add Ginkgo suite and test for plugin manager auto-registration
Added a Ginkgo v2 suite bootstrap (plugins_suite_test.go) for the plugins package and a test (manager_test.go) to verify that plugins in the testdata folder are auto-registered and can be loaded as agents. The test uses a mock DataStore and asserts that the agent is registered and its AgentName matches the plugin directory. Updated go.mod and go.sum for wazero dependency required by plugin WASM support.
* test(plugins): ensure test WASM plugin is always freshly built before running suite; add real-plugin Ginkgo tests. Add BeforeSuite to plugins suite to build plugins/testdata/agent/plugin.wasm using Go WASI build command, matching README instructions. Remove plugin.wasm before build to guarantee a clean build. Add full real-plugin Ginkgo/Gomega tests for wasmAgent, covering all methods and error cases. Fix manager_test.go to use pointer to Manager. This ensures plugin tests are always run against a freshly compiled WASM binary, increasing reliability and reproducibility.
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement persistent compilation cache for WASM agent plugins
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement instance pooling for wasmAgent to improve resource management
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): enhance logging for wasmAgent and plugin manager operations
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement HttpService for handling HTTP requests in WASM plugins
Also add a sample Wikimedia plugin
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): standardize error handling in wasmAgent and MinimalAgent
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: clean up wikimedia plugin code
Standardized error creation using 'errors.New' where formatting was not needed. Introduced a constant for HTTP request timeouts. Removed commented-out log statement. Improved code comments for clarity and accuracy.
* refactor: use unified SPARQLResult struct and parser for SPARQL responses
Introduced a single SPARQLResult struct to represent all possible SPARQL response fields (sitelink, wiki, comment, img). Added a parseSPARQLResult helper to unmarshal and check for empty results, simplifying all fetch functions and improving type safety and maintainability.
* feat(plugins): improve error handling in HTTP request processing
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: background plugin compilation, logging, and race safety
Implemented background WASM plugin compilation with concurrency limits, proper closure capture, and global compilation cache to avoid data races. Added debug and warning logs for plugin compilation results, including elapsed time. Ensured plugin registration is correct and all tests pass.
* perf: implement true lazy loading for agents
Changed agent instantiation to be fully lazy. The Agents struct now stores agent names in order and only instantiates each agent on first use, caching the result. This preserves agent call order, improves server startup time, and ensures thread safety. Updated all agent methods and tests to use the new pattern. No changes to agent registration or interface. All tests pass.
* fix: ensure wasm plugin instances are closed via runtime.AddCleanup
Introduced runtime.AddCleanup to guarantee that the Close method of WASM plugin instances is called, even if they are garbage collected from the sync.Pool. Modified the sync.Pool.New function in manager.go to register a cleanup function for each loaded instance that implements Close. Updated agent.go to handle the pooledInstance wrapper containing the instance and its cleanup handle. Ensured cleanup.Stop() is called before explicitly closing an instance (on error or agent shutdown) to prevent double closing. This fixes a potential resource leak where instances could be GC'd from the pool without proper cleanup.
* refactor: break down long functions in plugin manager and agent
Refactored plugins/manager.go and plugins/agent.go to improve readability and reduce function length. Extracted pool initialization logic into newPluginPool and background compilation/agent factory logic into precompilePlugin/createAgentFactory in manager.go. Extracted pool retrieval/validation and cleanup function creation into getValidPooledInstance/createPoolCleanupFunc in agent.go.
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): rename wasmAgent to wasmArtistAgent
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(api): add AlbumMetadataService with AlbumInfo and AlbumImages requests
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugin): rename MinimalAgent for artist metadata service
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(api): implement wasmAlbumAgent for album metadata service with GetAlbumInfo and GetAlbumImages methods
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): simplify wasmAlbumAgent and wasmArtistAgent by using wasmBasePlugin
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add support for ArtistMetadataService and AlbumMetadataService in plugin manager
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): enhance plugin pool creation with custom runtime and precompilation support
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): implement generic plugin pool and agent factory for improved service handling
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): reorganize plugin management
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): improve function signatures for clarity and consistency
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement background precompilation for plugins and agent factory creation
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): include instanceID in logging for better traceability
Signed-off-by: Deluan <deluan@navidrome.org>
* test(plugins): add tests for plugin pre-compilation and agent factory synchronization
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add minimal album test agent plugin for AlbumMetadataService
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): rename fake artist and album test agent plugins for metadata services
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(makefile): add Makefile for building plugin WASM binaries
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add FakeMultiAgent plugin implementing Artist and Album metadata services
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): remove log statements from FakeArtistAgent and FakeMultiAgent methods
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: split AlbumInfoRetriever and AlbumImageRetriever, update all usages
Split the AlbumInfoRetriever interface into two: AlbumInfoRetriever (for album metadata) and AlbumImageRetriever (for album images), to better separate concerns and simplify implementations. Updated all agents, providers, plugins, and tests to use the new interfaces and methods. Removed the now-unnecessary mockAlbumAgents in favor of the shared mockAgents. Fixed a missing images slice declaration in lastfm agent. All tests pass except for known ignored persistence tests. This change reduces code duplication, improves clarity, and keeps the codebase clean and organized.
* feat(plugins): add Cover Art Archive AlbumMetadataService plugin for album cover images
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: remove wasm module pooling
it was causing issues with the GC and the Close methods
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: rename metadata service files to adapter naming convention
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: unify album and artist method calls by introducing callMethod function
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: unify album and artist method calls by introducing callMethod function
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: handle nil values in data redaction process
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: add timeout for plugin compilation to prevent indefinite blocking
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: implement ScrobblerService plugin with authorization and scrobbling capabilities
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: simplify generalization
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: tests
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: enhance plugin management by improving scanning and loading mechanisms
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: update plugin creation functions to return specific interfaces for better type safety
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: enhance wasmBasePlugin to support specific plugin types for improved type safety
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: implement MediaMetadataService with combined artist and album methods
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: improve MediaMetadataService plugin implementation and testing structure
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: add tests for Adapter Media Agent and improve plugin documentation
Signed-off-by: Deluan <deluan@navidrome.org>
* docs: add README for Navidrome Plugin System with detailed architecture and usage guidelines
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: enhance agent management with plugin loading and caching
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: update agent discovery logic to include only local agent when no config is specified
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: encapsulate agent caching logic in agentCache struct\n\nReplaced direct map/mutex usage for agent caching in Agents with a dedicated agentCache struct. This improves readability, maintainability, and testability by centralizing TTL and concurrency logic. Cleaned up comments and ensured all linter and test requirements are met.
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: correct file extension filter in goimports command
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: use defer to unlock the mutex
Signed-off-by: Deluan <deluan@navidrome.org>
* chore: move Cover Art Archive AlbumMetadataService plugins to an example folder
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: handle errors when creating media metadata and scrobbler service plugins
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: increase compilation timeout to one minute
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add configurable plugin compilation timeout
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: implement plugin scrobbler support in PlayTracker
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add context management and Stop method to buffered scrobbler
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add username field to scrobbler requests and update logging
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: data race in test
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: rename http proto files to host and update references
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: remove unused plugin registration methods from manager
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: extend plugin manifests and implement plugin management commands
Signed-off-by: Deluan <deluan@navidrome.org>
* Update utils/files.go
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
* fix for code scanning alert no. 43: Arbitrary file access during archive extraction ("Zip Slip")
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* feat: add plugin dev workflow support
Added new CLI commands to improve plugin development workflow: 'plugin dev' to create symlinks from development directories to plugins folder, 'plugin refresh' to reload plugins without restarting Navidrome, enhanced 'plugin remove' to handle symlinked development plugins correctly, and updated 'plugin list' to display development plugins with '(dev)' indicator. These changes make the plugin development workflow more efficient by allowing developers to work on plugins in their own directories, link them to Navidrome without copying files, refresh plugins after changes without restart, and clean up safely.
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement timer service with register and cancel functionality - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement timer service with register and cancel functionality - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement timer service with register and cancel functionality - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement timer service with register and cancel functionality
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: lint errors
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(README): update documentation to include TimerCallbackService and its functionality
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add InitService with OnInit method and initialization tracking - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add tests for InitService and plugin initialization tracking
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): expand documentation on plugin system implementation and architecture
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: panic
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): redirect plugins' stderr to logs
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add safe accessor methods for TimerService
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add plugin-specific configuration support in InitRequest and documentation
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add TimerCallbackService plugin adapter and integration
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): rename services for consistency and clarity
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add mutex for configuration access and clone plugin config
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(tests): remove configtest dependency to prevent data races in integration tests
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): remove PluginName method from WASM plugin implementations and update LoadPlugin to accept service type
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement instance pooling for wasmBasePlugin to improve performance - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add wasmInstancePool for managing WASM plugin instances with TTL and max size
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(plugins): correctly pass error to done function in wasmBasePlugin
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): rename service types to capabilities for consistency
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): simplify instance management in wasmBasePlugin by removing error handling in closure
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): update wasmBasePlugin and wasmInstancePool to return errors for better error handling
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): rename InitService to LifecycleManagement for consistency
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): fix instance ID logging in wasmBasePlugin
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): extract instance ID logging to a separate function in wasmBasePlugin, to avoid vet error
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): make timers be isolated per plugin
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): make timers be isolated per plugin
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugins): rename HttpServiceImpl to httpServiceImpl for consistency and improve logging
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add config service for plugin-specific configuration management
Signed-off-by: Deluan <deluan@navidrome.org>
* Update plugins/manager.go
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
* Update plugins/manager.go
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
* feat(crontab): implement crontab service for scheduling and canceling jobs
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(singleton): fix deadlock issue when a constructor calls GetSingleton again
Signed-off-by: Deluan <deluan@navidrome.org> (+1 squashed commit)
Squashed commits:
[325a96ea2] fix(singleton): fix deadlock issue when a constructor calls GetSingleton again
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(scheduler): implement Scheduler for one-time and recurring job scheduling, merging CrontabService and TimerService
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(scheduler): race condition in the scheduleOneTime and scheduleRecurring methods when replacing jobs with the same ID
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(scheduler): consolidate job scheduling logic into a single helper function
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(plugin): rename GetInstance method to Instantiate for clarity
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add WebSocket service for handling connections and messages
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(crypto-ticker): add WebSocket plugin for real-time cryptocurrency price tracking
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(websocket): enhance connection management and callback handling
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(manager): only create one adapter instance for each adapter/capability pair
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(websocket): ensure proper resource management by closing response body and use defer to unlocking mutexes
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: flaky test
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugin): refactor WebSocket service integration and improve error logging
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugin): add SchedulerCallback support and improve reconnection logic
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: test panic
Signed-off-by: Deluan <deluan@navidrome.org>
* docs: add crypto-ticker plugin example to README
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(manager): add LoadAllPlugins and LoadAllMediaAgents methods with slice.Map integration
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(api): add Timestamp field to ScrobblerNowPlayingRequest and update related methods
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(websocket): add error field to response messages for better error handling
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(cache): implement CacheService with string, int, float, and byte operations
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(tests): update buffered scrobbler tests for improved scrobble verification and use RWMutex in mock repo
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(cache): simplify cache service implementation and remove unnecessary synchronization
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(tests): add build step for test plugins in the test suite
Signed-off-by: Deluan <deluan@navidrome.org>
* wip
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(scheduler): implement named scheduler callbacks and enhance Discord plugin integration
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(rpc): enhance activity image processing and improve error handling in Discord integration
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(discord): enhance activity state with artist list and add large text asset
Signed-off-by: Deluan <deluan@navidrome.org>
* fix tests
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(artwork): implement ArtworkService for retrieving artwork URLs
Signed-off-by: Deluan <deluan@navidrome.org>
* Add playback position to scrobble NowPlaying (#4089)
* test(playtracker): cover playback position
* address review comment
Signed-off-by: Deluan <deluan@navidrome.org>
---------
Signed-off-by: Deluan <deluan@navidrome.org>
* fix merge
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: remove unnecessary check for empty slice in Map function
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: update reflex.conf to include .wasm file extension
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(scanner): normalize attribute strings and add edge case tests for PID calculation
Relates to https://github.com/navidrome/navidrome/issues/4183#issuecomment-2952729458
Signed-off-by: Deluan <deluan@navidrome.org>
* test(ui): fix warnings (#4187)
* fix(ui): address test warnings
* ignore lint error in test
Signed-off-by: Deluan <deluan@navidrome.org>
---------
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor(server): optimize top songs lookup (#4189)
* optimize top songs lookup
* Optimize title matching queries
* refactor: simplify top songs matching
* improve error handling and logging in track loading functions
Signed-off-by: Deluan <deluan@navidrome.org>
* test: add cases for fallback to title matching and combined MBID/title matching
Signed-off-by: Deluan <deluan@navidrome.org>
---------
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(ui): playlist details overflow in spotify-based themes (#4184)
* test: ensure playlist details width
* fix(test): simplify expectation for minWidth in NDPlaylistDetails
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(test): test all themes
Signed-off-by: Deluan <deluan@navidrome.org>
---------
Signed-off-by: Deluan <deluan@navidrome.org>
* chore(deps): update TagLib to version 2.1 (#4185)
* chore: update cross-taglib
* fix(taglib): add logging for TagLib version
Signed-off-by: Deluan <deluan@navidrome.org>
---------
Signed-off-by: Deluan <deluan@navidrome.org>
* test: verify agents fallback (#4191)
* build(docker): downgrade Alpine version from 3.21 to 3.19, oldest supported version.
This is to reduce the image size, as we don't really need the latest.
Signed-off-by: Deluan <deluan@navidrome.org>
* fix tests
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(runtime): implement pooled WASM runtime and module for better instance management
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(discord-plugin): adjust timer delay calculation for track completion
Signed-off-by: Deluan <deluan@navidrome.org>
* resolve PR comments
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): implement cache cleanup by size functionality
Signed-off-by: Deluan <deluan@navidrome.org>
* fix(manager): return error from getCompilationCache and handle it in ScanPlugins
Signed-off-by: Deluan <deluan@navidrome.org>
* fix possible rce condition
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(docs): update README to include Cache and Artwork services
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(manager): add permissions support for host services in custom runtime - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(manifest): add permissions field to plugin manifests - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* test(permissions): implement permission validation and testing for plugins - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(plugins): add unauthorized_plugin to test permission enforcement - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(docs): add Plugin Permission System section to README - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(manifest): add detailed reasons for permissions in plugin manifests - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(permissions): implement granular HTTP permissions for plugins - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(permissions): implement HTTP and WebSocket permissions for plugins - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: unexport all plugins package private symbols
Signed-off-by: Deluan <deluan@navidrome.org>
* update docs
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: rename plugin_lifecycle_manager
Signed-off-by: Deluan <deluan@navidrome.org>
* docs: add discord-rich-presence plugin example to README
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add support for PATCH, HEAD, and OPTIONS HTTP methods
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: use folder names as unique identifiers for plugins
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: read config just once, to avoid data race in tests
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: rename pluginName to pluginID for consistency across services
Signed-off-by: Deluan <deluan@navidrome.org>
* fix: use symlink name instead of folder name for plugin registration
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: update plugin output format to include ID and enhance README with symlink usage
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: implement shared plugin discovery function to streamline plugin scanning and error handling
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: show plugin permissions in `plugin info`
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add JSON schema for Navidrome Plugin manifest and generate corresponding Go types - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: implement typed permissions for plugins to enhance permission handling
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: refactor plugin permissions to use typed schema and improve validation - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: update HTTP permissions handling to use typed schema for allowed URLs - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: remove unused JSON schema validation for plugin manifests
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: remove unused fields from PluginPackage struct in package.go
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: update file permissions in tests and remove unused permission parsing function
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: refactor test plugin creation to use typed permissions and remove legacy helper
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: add website field to plugin manifests and update test cases
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: permission schema to use basePermission structure for consistency
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: enhance host service management by adding permission checks for each service
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: reorganize code files
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: simplify custom runtime creation by removing compilation cache parameter
Signed-off-by: Deluan <deluan@navidrome.org>
* doc: add WebSocketService and update ConfigService for plugin-specific configuration
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: implement WASM loading optimization to enhance plugin instance creation speed
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: rename custom runtime functions and update related tests for clarity
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: enhance plugin structure with compilation handling and error reporting
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: improve logging and context tracing in runtime and wasm base plugin
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: enhance runtime management with scoped runtime and caching improvements
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: implement EnsureCompiled method for improved plugin compilation handling
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: implement cached module management with TTL for improved performance
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: replace map with sync.Map
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: adjust time tolerance in scrobble buffer repository tests to avoid flakiness
Signed-off-by: Deluan <deluan@navidrome.org>
* refactor: enhance image processing with fallback mechanism for improved error handling
Signed-off-by: Deluan <deluan@navidrome.org>
* docs: review test plugins readme
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: set default timeout for HTTP client to 10 seconds
Signed-off-by: Deluan <deluan@navidrome.org>
* feat: enhance wasm instance pool with concurrency limits and timeout settings
Signed-off-by: Deluan <deluan@navidrome.org>
* feat(discordrp): implement caching for processed image URLs with configurable TTL
Signed-off-by: Deluan <deluan@navidrome.org>
---------
Signed-off-by: Deluan <deluan@navidrome.org>
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>