pear-devs/pear-desktop
43.7
Weak · 20 September 2026
29.6k
lines of production code
TypeScript
primary language
1
measurement over time
What this system is
This system is a desktop application wrapper for YouTube Music, built on Electron and TypeScript, designed to enhance the web interface through a modular plugin architecture. It provides core media control capabilities, including playback management, queue handling, and a local API server for external integration. The system supports extensive customization via plugins for audio processing, visual theming, synchronization, and ad-blocking, while maintaining a modernized build infrastructure with Vite and SolidJS.
How it got here
2019–2023 — TypeScript migration and plugin architecture rewrite
51 changes.
The project underwent a comprehensive architectural overhaul, migrating from plain JavaScript to TypeScript and adopting Vite for the build system. This period focused on establishing a robust, modular plugin infrastructure with a new API, SolidJS UI components, and internationalization support. Legacy plugins were removed or refactored, while new features like synchronized listening and advanced audio controls were introduced within the modernized framework.
2024–2026 — Plugin ecosystem expansion and SolidJS migration
28 changes.
This period focused on significantly expanding the application's plugin ecosystem by introducing new features such as synced lyrics, an API server, equalizer support, and ad blocking. Concurrently, the codebase underwent a substantial migration of plugin UIs from raw HTML to SolidJS, enhancing performance and maintainability across the interface.
Features
Add Amuse plugin for song query API
A new Amuse plugin has been added to the application, introducing a local HTTP server (port 9863) that exposes a song query API. This plugin registers a backend service using the Hono framework, which listens on \/query\ and \/api\ endpoints to return current playback state (including track title, artist, duration, cover art, and seek position) in a structured JSON format. The plugin is disabled by default and requires a restart to enable, providing a standardized interface for external clients to query media information.
src/plugins/amuse · high confidence
Add Clock plugin widget
A new Clock plugin has been added to the system, providing a widget that displays the current time. Users can enable the widget and configure it via the settings menu to toggle the display of seconds and switch between 12-hour and 24-hour time formats. The widget renders in the center content area and updates every second.
src/plugins/clock · high confidence
Add Do Not Track plugin for video ad blocking
A new 'Do Not Track' plugin is introduced, providing two modes for blocking video advertisements: 'In Player' mode, which uses JavaScript injection to prune ad-related properties from player responses (primarily targeting YouTube), and 'With Blocklists' mode, which leverages the Ghostery adblocker engine to filter network requests. The plugin includes configuration options to enable/disable the feature, toggle caching of blocklists, specify additional filter lists, and disable default lists, with a UI menu allowing users to switch between the two blocking strategies.
src/plugins/do-not-track · high confidence
Add Equalizer Plugin with Bass Booster Preset
A new equalizer plugin has been introduced, allowing users to apply audio filters via the application menu. The plugin currently includes a 'bass-booster' preset that utilizes a low-shelf filter (80 Hz, +12 dB gain) to enhance low-frequency audio. Users can toggle this preset on or off through the plugin's configuration menu, and the filters are automatically applied to audio sources when playback begins.
src/plugins/equalizer · high confidence
Add LumiaStream plugin for media control integration
A new plugin named 'LumiaStream' has been added to the application. It integrates with a local web server running on port 39231 to synchronize media playback status. The plugin listens for song information changes and sends POST requests to the local API endpoint, transmitting details such as track title, artist, duration, progress, and playback state (playing/paused) to enable external control or display of media information.
src/plugins/lumiastream · high confidence
Add Music Together plugin for synchronized listening
Introduces the new Music Together plugin, enabling users to host or join a synchronized listening session. The plugin provides a peer-to-peer connection layer (using PeerJS with STUN/TURN servers) to sync the queue, playback progress, and user profiles across clients. It includes a UI with host and guest popups for managing permissions, copying connection IDs, and disconnecting, along with status indicators and styling for the shared experience.
src/plugins/music-together · high confidence
Add Music Together queue management plugin
Introduces the new Music Together plugin, which adds queue management capabilities to the application. The implementation includes a client module for generating authentication headers and extracting tokens, a core queue class that handles video list synchronization and dispatches state updates, and utility functions for mapping queue items and computing SHA-1 hashes for API requests.
src/plugins/music-together/queue · high confidence
Add SOCKS5 authenticated proxy adapter backend
The auth-proxy-adapter backend now implements a SOCKS5 proxy server that listens on a configurable port and hostname. It intercepts client connections, performs SOCKS5 handshakes (supporting IPv4, IPv6, and domain targets), and forwards traffic through an upstream proxy URL defined in the application settings. This allows users to route their application's network traffic through a SOCKS5 proxy with authentication support.
src/plugins/auth-proxy-adapter/backend · high confidence
Add UI templates for the Music Together plugin
The Music Together plugin now includes its user interface structure, adding HTML templates for the settings button, status display, menu items, and popups. These templates define the layout for the plugin's navigation bar icon, connection status indicators, user lists, and context menu entries within the YTMusic interface.
src/plugins/music-together/templates · high confidence
Add Unobtrusive Player plugin
A new plugin is introduced that manages the visibility of the YouTube Music player page to keep the interface unobtrusive. When enabled, the plugin hides the player page and its background elements after a user plays a song, automatically closing the player view when the video changes. It specifically handles play triggers from the player bar, song play buttons, and the shuffle play menu item, ensuring the main content remains visible while the player is effectively dismissed.
src/plugins/custom-output-device, src/plugins/unobtrusive-player · high confidence
Add audio compressor plugin to fix real-time and duplication bugs
A new audio compressor plugin has been added to the system, introducing a DynamicsCompressorNode with specific settings (threshold -50, ratio 12, knee 40) to process audio in real-time. This plugin addresses reported issues regarding real-time behavior and duplicated audio by managing the connection between audio sources and the compressor node via a dedicated Storage class, ensuring proper cleanup on stop. The plugin is fully internationalized, using the i18n system for its name and description.
src/plugins · high confidence
Add configuration and menu for the Auth Proxy Adapter plugin
Introduces the Auth Proxy Adapter plugin, providing a new configuration interface that allows users to enable or disable the proxy and adjust its hostname and port settings via the application menu. The plugin is registered with a default configuration (disabled, localhost:4545) and requires a restart to apply changes, with the feature marked as added in version 3.10.X.
src/plugins/auth-proxy-adapter · high confidence
Add macOS Touch Bar plugin for music controls
Introduces a new plugin that adds a Touch Bar interface on macOS, allowing users to control music playback directly from the Touch Bar. The plugin displays the current song title and album art, and provides buttons for previous track, play/pause, next track, dislike, and like. It integrates with the application's song control system to update the display in real-time as the song changes.
src/plugins/touchbar · high confidence
Add navigation plugin with Material UI 3 back/forward buttons
A new navigation plugin has been added that renders back and forward buttons using Material UI 3 components (mdui-button-icon, mdui-tooltip) and SolidJS. The plugin integrates with the existing LitElement wrapper to display chevron icons and injects the button container into the \#right-content area, providing users with standard browser navigation controls.
src/plugins/navigation · high confidence
Added TypeScript declarations for Kuroshiro and Kuromoji analyzers
TypeScript type definitions have been added for the \kuroshiro\ and \kuroshiro-analyzer-kuromoji\ libraries, enabling proper type checking for Japanese text conversion features. The \Kuroshiro\ declaration exposes the \convert\ method, which supports outputting text in hiragana, katakana, or romaji (with specific romaji systems like Hepburn or Passport), and includes utility functions for detecting and converting Japanese character types. The \KuromojiAnalyzer\ declaration provides the interface for initializing and parsing text, which is required by the main Kuroshiro class to perform these conversions.
src/ts-declarations · high confidence
Added plugin to automatically skip songs marked as disliked
A new plugin has been introduced that monitors the video player for a 'dislike' status and automatically clicks the next button to skip the track. The implementation uses a MutationObserver on the like/dislike button element to detect when a song is disliked and triggers the skip action immediately.
src/plugins/skip-disliked-songs · high confidence
Ambient Mode plugin adds configurable blur effects for images and videos
The Ambient Mode plugin now provides a dedicated settings menu allowing users to customize the visual blur effect applied to song images and video backgrounds. Users can adjust parameters including transition smoothness (interpolation time), rendering quality, effect size, buffer rate, blur intensity, opacity, and a fullscreen toggle. The plugin injects a blurred image overlay for static covers and a real-time canvas-based blur for video players, with CSS adjustments to prevent UI element overlap.
src/plugins/ambient-mode · high confidence
Downloader plugin backend implementation
The main backend logic for the downloader plugin has been implemented in the \src/plugins/downloader/main\ directory. This includes \index.ts\, which handles the core download orchestration using \youtubei.js\ and \ffmpeg.wasm\, manages premium status detection via the YouTube Music UI, and handles file writing and metadata tagging. The \utils.ts\ file provides helper functions for folder resolution, image cropping, and UI feedback. This change establishes the foundational backend capabilities for the downloader feature.
src/plugins/downloader/main · high confidence
Expanded synced lyrics sources with new providers
The synced lyrics plugin now supports four additional lyric sources: LRCLib, Genius, Musixmatch, and YouTube Music. This expands the available options for finding synchronized and plain lyrics, increasing the likelihood of finding accurate results for a wider variety of tracks.
src/plugins/synced-lyrics/providers · high confidence
Initial i18n module implementation
Added a new i18n module (src/i18n/index.ts) that initializes the i18next library with virtual language resources, sets English as the default and fallback language, and exposes functions to load translations, change the active language, and access the translation function.
src/i18n · high confidence
Introduce API Server plugin with HTTPS and authentication configuration
The API Server plugin is now available, allowing users to enable a local API server via the settings menu. Users can configure the server's hostname and port, choose between authentication strategies (auth at first or none), and optionally enable HTTPS by providing custom certificate and key paths. The plugin is disabled by default.
src/plugins/api-server · high confidence
Introduce API server authentication, control endpoints, and real-time WebSocket updates
The API server plugin now includes a new authentication route at /auth/{id} that issues JWT access tokens, supporting configurable strategies (none or interactive dialog) to authorize client IDs. A comprehensive control module exposes endpoints for playback management (play, pause, toggle, previous, next), media interaction (like, dislike, seek, go-back, go-forward), and queue operations (add, move, get next). Additionally, a WebSocket endpoint at /api/v1/ws provides real-time streaming of player state changes—including song info, play/pause status, position, volume, repeat, and shuffle—allowing clients to maintain synchronized state without polling.
src/plugins/api-server/backend/routes · high confidence
Introduce API server backend with HTTPS, WebSocket, and JWT authentication
The API server backend has been restructured into a new modular implementation using the Hono framework. This change introduces support for HTTPS connections with custom certificate configuration, enabling secure remote control. It also adds a WebSocket endpoint at \/api/v1/ws\ for real-time state updates and implements JWT-based authentication with explicit algorithm enforcement (HS256) to secure API access. The backend now exposes player state (repeat mode, volume, like status) via IPC listeners and provides Swagger documentation for the v1 API.
src/plugins/api-server/backend · high confidence
Introduce In-App Menu plugin with custom title bar and platform-specific defaults
The new in-app-menu plugin replaces the native window chrome with a custom title bar and menu system. It introduces a configuration interface allowing users to toggle the menu's visibility and, on Linux, hide DOM window controls. The plugin registers a backtick key shortcut to toggle the menu, handles window management actions (minimize, maximize, close) via IPC, and applies CSS adjustments to prevent layout shifts and scrolling lag in large playlists. By default, the menu is enabled on Windows and macOS but disabled on Linux, aligning with platform conventions.
src/plugins/in-app-menu · high confidence
Introduce Synced Lyrics plugin with customizable display and provider options
A new Synced Lyrics plugin is added, allowing users to display synchronized, time-coded lyrics with customizable line effects (fancy, scale, offset, focus), romanization, and Chinese character conversion. The plugin supports multiple lyric providers, lets users select a preferred source, and includes settings for precise timing and default text strings. It replaces the original lyrics view with a styled, animated display that can be toggled via the plugin menu.
src/plugins/synced-lyrics · high confidence
Introduce comprehensive TypeScript type definitions for the application
The \src/types\ directory has been populated with a new set of TypeScript definition files that formally type the application's internal state, API responses, and plugin architecture. This includes detailed interfaces for the player's state (\datahost-get-state\), YouTube API responses (\get-player-response\, \player-api-events\), and the \MusicPlayer\ interface, ensuring stricter type checking for media playback logic. Additionally, a structured plugin system is now defined with \PluginDef\, \PluginConfig\, and distinct context interfaces (\BackendContext\, \RendererContext\, etc.) in \contexts.ts\ and \plugins.ts\, enabling better integration for features like synced lyrics and menu extensions. Supporting types for UI elements (icons, toasts, queues) and platform-specific contexts (Electron IPC) are also included to improve developer experience and code reliability.
src/types · high confidence
Introduce plugin system type definitions and configuration utilities
Added new TypeScript type definitions for a plugin system, including interfaces for Config, Plugin, RendererPlugin, MainPlugin, PreloadPlugin, and MenuPlugin, along with a utility function definePluginConfig to manage plugin configurations. This establishes the foundational types and configuration mechanism for the new plugin architecture.
src/plugins/utils/common · high confidence
Introduction of the Shortcuts plugin with MPRIS integration
A new Shortcuts plugin has been added, allowing users to configure global and local keyboard shortcuts for previous, play/pause, and next actions via the application menu. The plugin includes an option to override system media keys and, on Linux, integrates with MPRIS to expose player controls (play, pause, seek, volume, shuffle, repeat) to the desktop environment.
src/plugins/shortcuts · high confidence
LRC synced lyrics parser now supports karaoke word timings and metadata tags
The LRC parser in the synced-lyrics plugin has been updated to handle more complex LRC formats. It now correctly parses metadata tags (such as artist, album, title, and length) and extracts individual word-level timings for karaoke-style lyrics. Additionally, the parser applies an offset value found in the LRC file to all timestamps and ensures the timeline starts at zero if the first lyric line appears after 300ms.
src/plugins/synced-lyrics/parsers · high confidence
New API request and response schemas for media control and queue management
The API server now defines strict validation schemas for several new and existing endpoints, ensuring consistent data handling for users. New capabilities include queue management with support for inserting songs at specific positions (end or after current), remote control features like absolute seeking, go-back/go-forward by seconds, volume and fullscreen toggling, and repeat iteration. Additionally, search endpoints now support optional parameters and continuations, and song info responses include detailed metadata such as media type and view counts.
src/plugins/api-server/backend/scheme · high confidence
New Scrobbler Plugin with Last.fm and ListenBrainz support
A new Scrobbler plugin has been added, allowing users to automatically scrobble playback history to Last.fm and ListenBrainz. The plugin includes configuration options to enable or disable each service, as well as toggles to scrobble non-music media (such as podcasts and videos) and to use alternative titles or artist names for more accurate matching. Users can configure API credentials and service settings directly through the plugin's menu interface.
src/plugins/scrobbler · high confidence
New Transparent Player plugin for window transparency effects
A new plugin has been added that allows users to apply transparency effects to the application window, supporting Windows materials (Acrylic, Mica, Tabbed) and macOS vibrancy styles. Users can configure the effect type and opacity via the plugin menu, with the plugin handling both the backend window styling and frontend CSS adjustments for the player bar and navigation elements.
src/plugins/transparent-player · high confidence
New audio visualizer plugin with multiple rendering modes
A new visualizer plugin has been added to the application, allowing users to overlay audio-reactive graphics on the video player. The plugin supports three distinct visualizer types: Butterchurn (a classic fractal zoom visualizer), Vudio (offering waveform, circlewave, circlebar, and lighting effects), and a custom Wave visualizer (supporting animations like cubes and circles). Users can configure the visualizer type, specific effects, colors, and animation parameters via the plugin menu. The implementation includes TypeScript definitions for the underlying libraries and handles canvas rendering within the player container.
src/plugins/visualizer · high confidence
New performance improvement plugin with CPU and memory optimizations
A new 'performance-improvement' plugin has been added, which is enabled by default and requires a restart to take effect. This plugin injects two key optimizations: a 'CPU Tamer' that reduces CPU usage by throttling animation frames (using DOM mutation observers as a fallback if GPU acceleration is unavailable), and 'RM3', a memory management tool that tracks and reuses DOM elements to reduce garbage collection pressure.
src/plugins/performance-improvement · high confidence
New plugin to disable video autoplay
A new plugin has been added to allow users to prevent videos from playing automatically. The plugin listens for video data loading events and pauses the video, with an optional configuration to apply this behavior only once per session. It integrates with the application's internationalization system for its name, description, and menu label.
src/plugins/disable-autoplay · high confidence
New plugin utility API for CSS injection, file system checks, and fetch abstraction
The plugin system now exposes a new set of utility functions in the main process to assist plugin development. Plugins can inject CSS styles into web contents with automatic unregistration support, perform asynchronous file existence checks, and use an Electron-based fetch abstraction that leverages the \net\ module. Additionally, new type definitions (\defineMainPlugin\, \definePreloadPlugin\, \defineMenuPlugin\) are provided to standardize how plugins are defined and typed within the new plugin architecture.
src/plugins/utils/main · high confidence
New provider layer for app controls, song info, and protocol handling
The src/providers directory now contains a new set of TypeScript modules that centralize application control logic. app-controls.ts registers IPC handlers for restart, reload, and path resolution. song-controls.ts exposes a comprehensive API for playback, queue management, and volume control via IPC events. song-info.ts and song-info-front.ts handle the extraction of metadata (title, artist, album, media type) from YouTube Music, including specific workarounds for podcast content and image validation using HEAD requests. protocol-handler.ts registers the 'youtubemusic' custom protocol to allow external commands to control playback. decorators.ts provides utility functions like singleton, debounce, and cache for these providers.
src/providers · high confidence
New utility functions for plugin lifecycle, DOM waiting, and security policies
The src/utils directory now includes several new helper modules: custom-element.ts provides a factory for creating anonymous SolidJS-based custom elements; index.ts introduces core plugin lifecycle utilities (createPlugin, createBackend, createPreload, createRenderer, startPlugin, stopPlugin) that manage plugin execution contexts, handle 'this' binding, and log execution times using i18n; trusted-types.ts registers a default Trusted Types policy to allow safe HTML/script injection; wait-for-element.ts offers a configurable polling utility to wait for DOM elements with a default 100ms retry interval; and testing.ts exposes an isTesting helper. These changes enhance plugin extensibility, improve DOM interaction reliability, and enforce stricter content security policies.
src/utils · high confidence
New video-toggle and quality-changer plugins added
This change introduces two new plugins to the application. The video-toggle plugin allows users to control the visibility and mode of the video player in the YouTube Music interface, offering options to use a custom toggle button, the native YouTube switcher, or force-hide the video entirely, with configurable alignment. The quality-changer plugin adds a button to the player controls that lets users select from available audio quality levels via a system dialog, changing the playback quality on selection.
src/plugins/video-toggle · high confidence
Redesigned in-app menu with native-style controls and floating panels
The in-app menu renderer has been completely rewritten to provide a modern, native-feeling interface. The new design features a custom title bar with integrated window controls (minimize, maximize, close) that respect system drag regions, and a floating menu panel that intelligently positions itself using floating-ui middleware to prevent overflow. The menu items now support rich interactions including submenus, radio groups, checkboxes, and tooltips, all rendered with smooth CSS transitions and backdrop blur effects for a polished visual experience.
src/plugins/in-app-menu/renderer · high confidence
Removals
Adblocker plugin removed
The adblocker plugin has been completely removed from the application. This deletion eliminates the previous JavaScript-based ad-blocking implementation, which relied on the 'ad-block' library, a serialized 'detector.buffer' cache, and a separate generator script to fetch and parse ad lists from external sources.
plugins/adblocker · high confidence
Removal of legacy navigation plugin implementation
The navigation plugin's core logic has been removed, specifically the \actions.js\ module that defined channel constants and trigger functions, the \back.js\ module that handled window navigation events (goBack/goForward), and the \front.js\ module that injected forward and back buttons into the UI. This change eliminates the previous mechanism for triggering and handling page navigation within the application.
plugins/navigation · high confidence
Removal of legacy plugin store and helper modules
The application has removed the \store/index.js\ and \store/plugins.js\ files, which previously managed persistent settings (such as window size, URL, and plugin lists) and provided helper functions for enabling or disabling plugins. This change eliminates the legacy plugin management system and its associated configuration storage from the store module.
store · high confidence
Removal of legacy shortcut registration and YouTube-specific key mappings
The \back.js\ and \youtube.js\ files in the shortcuts plugin have been removed. This eliminates the previous implementation that registered global and local shortcuts (such as MediaPlayPause, next/previous track, and search) by injecting keyboard events (Space, j, k, /) into the web contents. Users will no longer have these specific legacy shortcut behaviors available through this plugin module.
plugins/shortcuts · high confidence
Removal of no-google-login plugin
The no-google-login plugin has been completely removed from the application. This eliminates the functionality that previously hid Google login buttons and related UI elements (such as the sign-in link and liked music tab) in YouTube Music, as well as the associated backend CSS injection and frontend DOM manipulation scripts.
plugins/no-google-login · high confidence
Removal of shared plugin utility module
The shared utility module \plugins/utils.js\ has been removed from the codebase. This module previously provided helper functions for plugin development, including DOM element creation from HTML strings or files, path resolution for templates, IPC action triggering and listening, file existence checks, and CSS injection logic. Its removal indicates that these capabilities are either being refactored into individual plugins, moved to a different location, or are no longer required in their current form.
plugins · high confidence
Removed legacy navigation template files
The \back.html\ and \forward.html\ template files within the navigation plugin have been deleted. These files previously contained the HTML structure for the previous and next page navigation controls, including their associated icons and click handlers. Their removal indicates that the navigation UI no longer relies on these specific static template definitions, likely as part of a broader refactoring to simplify the plugin's structure or migrate to a different rendering approach.
plugins/navigation/templates · high confidence
Architecture
Migrate application source code to the src directory
The application's source code has been reorganized into the src directory, introducing a new entry point structure with src/index.ts for the main process and src/renderer.ts for the UI. This change includes a new src/preload.ts for secure context bridging, src/menu.ts for the application menu, and src/tray.ts for system tray management. Supporting files such as src/music-player.css for styling, src/pear-desktop.ts for Vite module declarations, and various TypeScript definition files (e.g., src/navigation.d.ts, src/yt-web-components.d.ts) have been added to support the new build and type-checking setup.
src · high confidence
Migrate build tooling to TypeScript, Vite, and Oxlint
The project has been refactored from a plain JavaScript Electron app to a TypeScript-based architecture using Vite (via electron-vite) for bundling and Oxlint for linting. This change replaces the previous entry point scripts (index.js, menu.js, preload.js) and the XO linter with new configuration files (.oxlintrc.json, .oxfmtrc.json, electron.vite.config.mts) and a modernized plugin system. Users benefit from improved type safety, faster development builds, and a more robust plugin infrastructure that supports both backend and frontend injection.
(repo-wide) · high confidence
Behavioural changes
Add custom ESLint camelcase rule plugin
The tools directory now includes a new \eslint-core-plugin.mjs\ file that defines a custom ESLint rule for enforcing camelcase naming conventions. This plugin provides logic to detect and report identifiers that do not follow camelcase standards, supporting options to ignore destructuring, imports, and globals, as well as allowing specific patterns. This change is part of the broader migration from ESLint to oxlint, where this plugin serves as a compatibility layer or custom rule implementation for the linting configuration.
tools · high confidence
Added offline error page and updated application assets
The application now includes a dedicated offline error page (\assets/error.html\) that displays a 'Cannot load Pear Desktop' message with a retry button when the internet connection is lost. Additionally, the application icon has been updated to a new SVG version (\assets/icon.svg\), and the Material Design UI (MDUI) component library styles (\assets/mdui.css\) have been added to support the interface.
assets · high confidence
Album Actions plugin rewritten in SolidJS with new UI components
The Album Actions plugin has been migrated from raw HTML to JSX using the SolidJS framework. This change introduces dedicated UI components (LikeButton, DislikeButton, UnLikeButton, UnDislikeButton) that render interactive buttons for managing playlist likes and dislikes. The plugin now uses SolidJS signals to manage the visibility and styling of these buttons, allowing for dynamic updates when users interact with the playlist, such as toggling like/dislike states or loading full lists.
src/plugins/album-actions · high confidence
Album Color Theme plugin now applies dynamic theming across the entire UI
The album-color-theme plugin has been rewritten to extract dominant colors from album artwork and apply them as CSS variables throughout the application. This change extends the theme beyond the player to include the navigation bar, sidebar, and background elements, ensuring consistent color integration across all pages. Users can now configure the color mixing ratio and toggle seekbar theming via the plugin menu, while the underlying logic handles both light and dark mode adaptations automatically.
src/plugins/album-color-theme · high confidence
Audio visualizer implementations migrated to new plugin API
The visualizer components (Butterchurn, Vudio, and Wave) have been refactored to implement the new plugin API, introducing a shared abstract \Visualizer\ base class that standardizes audio node management and lifecycle methods like \resize\ and \destroy\. This change removes the previous requirement for application restarts when switching visualizers and ensures consistent cleanup of audio sources and animation frames across all three visualization modes.
src/plugins/visualizer/visualizers · high confidence
Captions selector plugin rewritten with new plugin API and SolidJS UI
The captions selector plugin has been completely rewritten to use the new plugin system, introducing a backend/renderer architecture. The user-facing UI is now built with SolidJS (TSX) instead of raw HTML, providing a captions settings button in the player controls that opens a native prompt to select or disable caption tracks. The plugin now supports configuration options for auto-loading the last selected caption and disabling captions entirely, with i18n support for all user-visible strings.
src/plugins/captions-selector · high confidence
Crossfade plugin migrated to new plugin API with i18n support
The crossfade plugin has been refactored to use the new plugin API, moving source code into the src directory and integrating internationalization (i18n) for plugin names, descriptions, and configuration prompts. The implementation now uses the \createPlugin\ utility and supports configurable fade scaling (linear, logarithmic, or custom dB), fade durations, and timing before track end, while maintaining the core volume fading logic via the \VolumeFader\ class.
src/plugins/blur-nav-bar, src/plugins/crossfade · high confidence
Discord Rich Presence plugin refactored with improved state management and new display options
The Discord plugin has been restructured into a modular service-based architecture (constants, service, timer manager, utils) to centralize logic and improve reliability. This update introduces throttled progress updates (15s throttle, 5s debounce) to reduce RPC spam, adds an inactivity timeout to clear activity when music is paused, and allows users to configure which field (title, artist, or application name) is displayed in the status. It also fixes Hangul character padding issues, adds URLs for songs and artists in the rich presence, and includes a 'Play on YouTube Music' button option.
src/plugins/discord · high confidence
Downloader plugin restructured with new finish-action settings and context menu integration
The downloader plugin has been rewritten to use the new plugin API and SolidJS (TSX), introducing a 'Download on finish' configuration that lets users automatically trigger a download after a specified time or percentage completion. The plugin now adds a download button directly to the context menu for songs, albums, and playlists, and supports customizable audio presets (including MP3, Source, and Custom) via FFmpeg arguments.
src/plugins/downloader · high confidence
Downloader template migrated to JSX
The download button template in the downloader plugin has been converted from raw HTML to JSX (TSX), enabling the use of SolidJS-style component syntax for rendering the download UI.
src/plugins/downloader/templates · high confidence
Exponential volume plugin now uses i18n and fixes volume desync
The exponential-volume plugin has been updated to support internationalization, with its name and description now retrieved via the i18n system. Additionally, a bug causing volume desynchronization has been fixed by implementing a synchronization loop that ensures the player's volume state remains consistent with the exponential scaling logic.
src/plugins/exponential-volume · medium confidence
Migrate plugin UI templates to JSX (SolidJS)
The UI templates for the captions selector, picture-in-picture, and playback speed plugins have been converted from raw HTML to JSX (TSX) using SolidJS syntax. This change updates the component definitions for the captions settings button, the picture-in-picture menu item, and the playback speed slider to use JSX expressions, ensuring consistent rendering and integration with the SolidJS framework.
src/plugins/captions-selector/templates, src/plugins/picture-in-picture/templates, src/plugins/playback-speed/components · high confidence
New Vite plugin infrastructure for code splitting and context-aware plugin loading
The build system now uses three new Vite plugins in the vite-plugins directory to improve modularity and performance. The i18n-importer plugin dynamically generates a virtual module to lazy-load internationalization resource files. The plugin-importer plugin generates virtual modules that handle plugin discovery and loading, using dynamic imports for the renderer and static imports for the preload context to ensure compatibility. The plugin-loader plugin performs static analysis on plugin source files to strip out context-specific properties (backend, preload, renderer, menu) based on the current build mode, enabling effective code splitting by ensuring each context only includes the necessary plugin code.
vite-plugins · high confidence
New renderer utility functions for DOM parsing and element creation
The \src/plugins/utils/renderer\ module now exports helper functions to safely parse HTML strings into DOM elements (\ElementFromHtml\) and create image elements from source URLs (\ImageElementFromSrc\), replacing previous raw HTML injection methods with a safer DOMParser-based approach. Additionally, new detection utilities (\isMusicOrVideoTrack\, \isAlbumOrPlaylist\, \isPlayerMenu\) have been added to identify specific YouTube Music UI components, enabling more precise context-aware rendering for plugin features.
src/plugins/utils/renderer · high confidence
Notifications plugin rewritten with platform-specific interactive and native modes
The notifications plugin has been completely rewritten to support distinct behaviors on Windows and Linux. On Windows, it now offers an 'interactive' mode that generates rich toast notifications with customizable XML templates (including logo, hero, and banner styles) and media control buttons (play, pause, next, previous), configurable via the plugin menu. On Linux, it uses standard native notifications with configurable urgency levels (low, normal, critical). The plugin also introduces new configuration options such as \trayControls\, \hideButtonText\, \refreshOnPlayPause\, and \unpauseNotification\, and ensures proper internationalization for plugin names, descriptions, and menu items.
src/plugins/notifications · high confidence
Picture-in-Picture plugin migrated to new architecture with native support
The Picture-in-Picture plugin has been rewritten to use the new plugin API, introducing a modular structure with separate backend, renderer, and menu handlers. This update adds support for native browser Picture-in-Picture mode via the 'useNativePiP' configuration option, allowing users to toggle PiP using the browser's native API or the app's custom window management. The plugin now features a dedicated menu for configuring options such as 'alwaysOnTop', 'savePosition', 'saveSize', and custom hotkeys, with all labels and descriptions localized via i18n. The renderer uses SolidJS for the PiP button component and implements robust event handling for window state changes, shortcut blocking, and UI adjustments specific to the PiP mode, including CSS improvements for visibility and drag behavior.
src/plugins/picture-in-picture · high confidence
Playback speed plugin migrated to SolidJS and new plugin API
The playback speed plugin has been rewritten to use the new plugin API and SolidJS (TSX) instead of raw HTML. This change introduces a new slider component for adjusting playback speed, supports internationalization (i18n) for the plugin name, description, and UI labels, and improves the menu detection logic to ensure the slider is correctly inserted into the player menu. The plugin now uses a MutationObserver to handle dynamic menu changes and ensures the playback rate is updated when the video element's rate changes.
src/plugins/playback-speed · high confidence
Plugin loader refactored into distinct lifecycle modules
The plugin loading logic in src/loader has been restructured into four separate modules (main.ts, menu.ts, preload.ts, renderer.ts) to handle specific plugin types and contexts. This change introduces distinct lifecycle management for backend, menu, preload, and renderer plugins, including dedicated functions for force-loading and force-unloading each type. The refactoring also updates the context creation for each plugin type to use specific interfaces (BackendContext, MenuContext, PreloadContext, RendererContext) and improves error handling and logging for plugin initialization and unloading failures.
src/loader · high confidence
Precise Volume plugin migrated to new plugin API with enhanced volume controls
The Precise Volume plugin has been rewritten to use the new plugin architecture, introducing a configuration menu for custom volume step sizes, local arrow key shortcuts, and global system shortcuts. The plugin now persists the last used volume level across sessions and provides a visual volume HUD overlay that adjusts its position based on the video player state. It also enables volume control via mouse wheel on both the player bar and the video element itself.
src/plugins/precise-volume · high confidence
Restructured configuration system with new defaults and migration logic
The application's configuration has been reorganized into a new modular structure under src/config, introducing a centralized defaults file (defaults.ts) that defines the schema for window settings, user options, and plugins. This change includes a new plugin configuration module (plugins.ts) for managing plugin states and options, and a store module (store.ts) that implements version-specific migrations to handle legacy settings. Notable migrations include renaming 'plugins.discord.listenAlong' to 'plugins.discord.playOnYouTubeMusic', migrating 'plugins.lastfm' data into the new 'plugins.scrobbler' structure, and removing deprecated plugins like 'plugins.visualizer' and 'plugins.picture-in-picture'.
src/config · high confidence
Scrobbler services now support alternative song titles and artists
The scrobbler plugin (Last.fm and Listenbrainz) now respects user-configured alternative titles and artists when sending playback data. If the 'alternativeTitles' and 'alternativeArtist' options are enabled and alternative metadata is available, the service will use those values instead of the default track title and artist name, improving compatibility with services that expect specific naming conventions.
src/plugins/scrobbler/services · high confidence
Skip Silences plugin now uses configurable audio analysis thresholds
The Skip Silences plugin has been rewritten to use a configurable audio analysis engine. Users can now control the silence detection sensitivity via the \threshold\ (set to -100 dB by default) and \smoothing\ parameters, and the plugin supports an \onlySkipBeginning\ configuration option to restrict skipping to the start of media. The implementation listens for audio playback events and automatically seeks forward when silence is detected, with the ability to restart the plugin if configuration changes require it.
src/plugins/skip-silences · high confidence
Synced Lyrics plugin rewritten in SolidJS with new UI components
The Synced Lyrics plugin's renderer has been migrated from raw HTML to JSX using the SolidJS framework, introducing a suite of new components including ErrorDisplay, LoadingKaomoji, NotFoundKaomoji, LyricsPicker, SyncedLine, and PlainLyrics. This rewrite enables improved user experience features such as animated loading indicators, better error handling with retry options, and a provider picker that allows users to select or star preferred lyrics sources. The new implementation also supports romanization display for lyrics and integrates with the Material Design UI components for a more consistent look.
src/plugins/synced-lyrics/renderer/components · high confidence
Synced Lyrics renderer rewritten with Solid.js and virtual scrolling
The Synced Lyrics plugin renderer has been completely rewritten to use Solid.js for the UI, replacing the previous implementation. This change introduces virtual scrolling via the 'virtua' library to handle large lyric lists more efficiently, and adds a reactive owner setup to manage component lifecycles. The renderer now supports multiple lyric providers, caching search results, and includes built-in romanization for Chinese, Japanese, Korean, Thai, Hindi, and Bengali lyrics, along with simplified/traditional Chinese conversion. The UI also features configurable line effects (fancy, scale, offset, focus) and a lyrics picker that appears based on scroll position and mouse interaction.
src/plugins/synced-lyrics/renderer · high confidence
Taskbar media control plugin now adapts icon colors to system theme
The taskbar media control plugin on Windows now dynamically switches between black and white icon sets for the previous, play/pause, and next buttons based on the current system theme (light or dark). This ensures the media control buttons in the taskbar thumbnail remain visible and aesthetically consistent regardless of whether the user is in light or dark mode, replacing the previous static icon usage.
src/plugins/taskbar-mediacontrol · high confidence
Tuna OBS plugin now sends alternative titles, tags, and song URLs
The Tuna OBS plugin has been updated to include additional metadata in the data sent to OBS, specifically alternative titles, tags, and the song's URL. This enhancement allows for richer display information in OBS scenes. The plugin also implements a 'lite mode' to handle connection issues gracefully and ensures the TCP socket is kept alive for reuse.
src/plugins/tuna-obs · high confidence
Fixes
Apply patches to resolve dependency compatibility and runtime issues
This update applies several patches to third-party dependencies to fix build and runtime errors. The \kuromoji\ library is patched to support modern Node.js environments (including \setImmediate\ and \util.types\), prevent infinite loops in iterators, and filter out \\_\proto\\_\ keys for security. The \electron-is\ library is extended to detect FreeBSD. The \mdui\ library is patched to remove React-specific type definitions and declare \solid-js\ as a peer dependency, aligning it with the project's framework. Finally, the \@malept/flatpak-bundler\ patch improves error reporting by including command arguments and output in rejection messages.
patches · high confidence
Test coverage
Added Playwright test for app launch and visibility; Added tests for segment sorting logic.
Dependencies
Routine dependency updates across the project
This release includes routine updates to various dependencies, including TypeScript, Vite, Electron, and ESLint, to keep the project up to date with the latest versions and improvements.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Baseline
- First survey — no prior run to compare against. CAI 44.
Lenses
- Code Health 51
- Architecture 56
- Maturity 53
- Readiness 40
- Security 46
- Accessibility 44
Changes since last survey
- 300 commits — 220 feature/other, 80 fixes
By area
- src/i18n — 139 commits
- (root) — 100 commits
- src/plugins — 28 commits
- .github/workflows — 22 commits
- (repo) — 3 commits
- src/config — 2 commits
- .github/ISSUE_TEMPLATE — 1 commit
- assets/generated — 1 commit
- assets/media-icons-white — 1 commit
- src/index.ts — 1 commit
- src/renderer.ts — 1 commit
- vite-plugins/plugin-importer.mts — 1 commit
Notable commits
- fix: Fix weblate link (#4204)
- fix: Fix: discord activity sanitizer (#4119)
- fix: Merge pull request #4374 from AARP41298/fix(synced-lyrics)
- fix: Revert "fix macos build (?)"
- fix: fix ajv peer dep
- fix: fix lrc tests
- fix: fix macos build (?)
- fix: fix tests
- fix: fix(actions): restrict permission
- fix: fix(api-server): add required 'alg' option to JWT middleware (#4368)
- fix: fix(auth-proxy, config): update type imports and enhance oxlint compliance
- fix: fix(back): fix captions selector handler name
- fix: fix(ci): fix CI/CD action
- fix: fix(deps): update @xmldom/xmldom version to 0.8.12
- fix: fix(deps): update dependency @floating-ui/dom to v1.7.5 (#4275)
- fix: fix(deps): update dependency @ghostery/adblocker-electron to v2.13.4 (#4255)
- fix: fix(deps): update dependency @ghostery/adblocker-electron-preload to v2.13.4 (#4257)
- fix: fix(deps): update dependency @hono/node-server to v1.19.9 (#4249)
- fix: fix(deps): update dependency @hono/node-ws to v1.3.0 (#4258)
- fix: fix(deps): update dependency @hono/swagger-ui to v0.5.3 (#4250)
- …and 280 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
pear-devs/pear-desktop was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 20 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit bd1172d37ff9ae6750e0a41e06a6e6305b15921d — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-b51f968c9b10.