Repository navigation
What's Changed
- ci(release): pin Linux builds and cap the notes by Bjarne Oeverli (@bjarneo) (
a8386f8) - docs(site): include WebM among the FFmpeg formats by Charlyls (@cartudev) (
05dd52e) - docs(site): list MP4 among the local audio formats by Charlyls (@cartudev) (
3bb9cc1) - style: gofmt the mp4 audio extension test by Charlyls (@cartudev) (
2cc9734) - feat(player): accept the audio stream of .mp4 files by Charlyls (@cartudev) (
0fc1e7a) - fix(ui): follow terminal colors in Ethereal by Bjarne Oeverli (@bjarneo) (
9928143) - feat(navidrome): add track ratings by manuaudio (@manuaudio) (
e30c677) - feat(netease): add a cookies_file option by JazibAli360 (@JazibAli360) (
8b1fe18) - fix(resolve): play on.soundcloud.com short links by Renan Bezerra Guimarães (@RenanBezerraGuima) (
5e36da0) - test(lyrics): make the repeated timestamps test table-driven, add fraction and BOM cases by Jay Hemnani (@jayhemnani9910) (
d708f65) - docs(playlists): say relative paths in a local PLS file resolve from its folder by Jay Hemnani (@jayhemnani9910) (
0424e29) - fix(nix): refresh the vendor hash after the Telegram provider by Charlyls (@cartudev) (
6f5a67e) - fix(nix): refresh the vendor hash for the Go 1.27 toolchain by Charlyls (@cartudev) (
1288b78) - fix(nix): build with the Go 1.27 toolchain by Charlyls (@cartudev) (
2385d92) - docs(mediactl): correct the --player=cliamp note by Bjarne Oeverli (@bjarneo) (
ac76422) - fix(ui): sanitize remote text before rendering (#685) by Acts1631 (@acts-1631) (
f1296c9) - feat(telegram): add a native MTProto Telegram provider (#651) by Carlos (@cartudev) (
a65244f) - feat(remote): add --params-file and --params-stdin to cliamp remote call (#641) by Renan Bezerra Guimarães (@RenanBezerraGuima) (
fda4d4b) - docs(plugins): list album_art_url in the event payloads (#654) by Carlos (@cartudev) (
87d929e) - feat(playlist): reverse the playlist order with Ctrl+O (#667) by Knut Åbjørsbråten (@Knutsi) (
6a6fb24) - fix(ui): align numbers in playlist search results (#674) by IgorM (@maliavko) (
93c54bc) - fix(plex): read the album year of a track (#676) by IgorM (@maliavko) (
34e4cad) - fix(tomlutil): match spaced and quoted headers by Ehab Kahwati (@Devehab) (
c329220) - fix(tomlutil): skip escaped quotes in """ strings by Ehab Kahwati (@Devehab) (
1d22a1c) - fix(tomlutil): tighten header detection by Ehab Kahwati (@Devehab) (
3c72a8b) - fix(tomlutil): handle header comments and [table] headers by Ehab Kahwati (@Devehab) (
aed5bb9) - fix(lyrics): show LRC lines at every time tag, in time order by Jay Hemnani (@jayhemnani9910) (
f490f07) - fix(radio): warn about unknown sections in radios.toml by Ehab Kahwati (@Devehab) (
0baf1cd) - fix(spotify): give album tracks the album's cover by BAK (@BAKocska) (
84096f8) - fix(resolve): resolve PLS paths against its folder by Jay Hemnani (@jayhemnani9910) (
cb09863) - fix(kittyimg): size the image before decoding it (#653) by Carlos (@cartudev) (
02309c9) - test(luaplugin): drop an unused layout fake field by Bjarne Oeverli (@bjarneo) (
d693e82) - feat(ipc): add a start index to provider.load (#626) by Chad Thackray (@ChadThackray) (
2a5e97b) - fix(luaplugin): stop logging a Lua error as a timeout (#625) by Chad Thackray (@ChadThackray) (
ebe3301) - fix(player): trim MP3 encoder delay and padding (#623) by rxvt (@rxvt) (
a33f600) - fix: bump Go to 1.26.10 for govulncheck by Bjarne Oeverli (@bjarneo) (
9d61173) - feat(bandcamp): stream your purchased collection (#521) by Lukasz Jagiello (@ljagiello) (
195d8ae) - refactor: add more constraints to lyrics and artist lookup by bl4zee (@bl4zee1g) (
620e9fe) - docs(plugins): document the image, layout, ui and vis APIs by Charlyls (@cartudev) (
1b71802) - fix(plugins): open image paths without blocking on a FIFO by Charlyls (@cartudev) (
28746d9) - fix(plugins): close the remaining review findings by Charlyls (@cartudev) (
270ebd6) - fix(plugins): address the review by Charlyls (@cartudev) (
0136634) - feat(plugins): render image panes as text blocks by Charlyls (@cartudev) (
1f88895) - feat(plugins): let plugins build panes, images and selectors by Charlyls (@cartudev) (
3aad360) - fix(plugins): validate and normalize allowed private address ports by Lukasz Chojnacki (@lchojnack) (
e2a1b8c) - feat(plugins): allow exact private addresses for self-hosted servers by Lukasz Chojnacki (@lchojnack) (
f11b49e) - fix: soundcloud: properly report artist by bl4zee (@bl4zee1g) (
c087629) - test(resolve): build a valid file URI for Windows paths by Jay Hemnani (@jayhemnani9910) (
45b2f38) - fix(resolve): accept the largest EXTINF duration by Jay Hemnani (@jayhemnani9910) (
96d3be9) - fix(resolve): play file:// entries in playlists by Jay Hemnani (@jayhemnani9910) (
f0bd99d) - fix(resolve): read EXTINF titles after attributes by Jay Hemnani (@jayhemnani9910) (
83ade3e) - feat(ui): add the Ethereal visualizer by Bjarne Oeverli (@bjarneo) (
5656a55) - fix(review): hide EQ shortcut in minimal layout by SomSamantray (@SomSamantray) (
9247dcc) - docs(eq): document previous preset shortcut by SomSamantray (@SomSamantray) (
1cd10a0) - feat(eq): add previous preset shortcut by SomSamantray (@SomSamantray) (
8651319) - docs: name Windows source build toolchain by SomSamantray (@SomSamantray) (
8f4f98f) - docs: clarify Windows source build requirements by SomSamantray (@SomSamantray) (
8408f49) - fix: bump Go and x/net for govulncheck by Bjarne Oeverli (@bjarneo) (
ce8c65f) - fix: skip a dead YouTube track and honor track limits by Bjarne Oeverli (@bjarneo) (
091a143) - fix(ui): open local files off the UI thread by Bjarne Oeverli (@bjarneo) (
645346c) - docs: match Windows config directory by Bjarne Oeverli (@bjarneo) (
c04406c) - fix:respect hidden help bar in full screen visualizer by Raushan Kumar (@raushankumar72) (
5d47a75) - docs(site): describe hidden-file scans by Bjarne Oeverli (@bjarneo) (
48c56a3) - feat(provider): find songs related to a Spotify or YouTube track (#581) by Gjermund Garaba (@gjermundgaraba) (
0e3afcf) - docs(site): note GNOME Keyring cookie dependency by jacobius (@jakovius) (
6237b70) - docs(ytmusic): include Debian and Ubuntu secretstorage package by jacobius (@jakovius) (
bd1face) - fix(setup): retain Chromium cookie-source example by jacobius (@jakovius) (
6f16c6e) - fix(resolve): skip dotfiles when scanning folders by Daniel Bae (@MrBeldum) (
7c05974) - fix(ui): report favorite toggles in the status line by Taha Sadough (@tahadx) (
080d0a8) - fix(ui): stop status messages from shifting the frame by Taha Sadough (@tahadx) (
d11bce4) - feat(radio): show live listener counts on cliamp radio rows by Taha Sadough (@tahadx) (
646b573) - chore: exclude website, docs and generated files from language stats by Taha Sadough (@tahadx) (
f4f0882) - fix(ui): Space advances only when marking tracks by Taha Sadough (@tahadx) (
0760dbd) - fix(ui): use a check for marked tracks instead of a star by Taha Sadough (@tahadx) (
f2a3318) - fix(ui): q closes the info, lyrics and device overlays by Taha Sadough (@tahadx) (
ea4e6f1) - fix(ui): q closes the playlist manager and queue overlays by Taha Sadough (@tahadx) (
56e7ed8) - docs: require a description body on every commit by Taha Sadough (@tahadx) (
2638110) - fix(ui): name key targets in help and drop dead n hints by Taha Sadough (@tahadx) (
ed39a3c) - fix(ui): keep overlays open when switching to an unconfigured provider by Taha Sadough (@tahadx) (
5675ddd) - fix(ui): reject non-terminal stdout by Neo Lehmann (@legacynode) (
2084402) - fix(ui): hint valid keys on stray presses in confirm prompts by Taha Sadough (@tahadx) (
d2c4d6e) - fix(ui): confirm before clearing the queue by Taha Sadough (@tahadx) (
792ad4e) - fix(ui): advertise q as a close key for overlays by Taha Sadough (@tahadx) (
cdd2679) - fix(ui): q exits the full-screen visualizer instead of quitting by Taha Sadough (@tahadx) (
dc4d489) - fix(ui): open playlist manager with p from any provider pane by Taha Sadough (@tahadx) (
0714c18) - feat(ui): show hidden shortcuts, hint unconfigured providers, clarify errors by Taha Sadough (@tahadx) (
575610f) - fix(ui): let Esc leave the provider browser with an empty playlist by david s (@davidszp) (
59d0ce4) - fix(spotify): rebuild the session when the access point closes by BAK (@BAKocska) (
355fc30) - feat(ui): add YinYang visualizer mode by Erik Johansson (@erikrjohansson) (
3e61ebe) - fix(radio): jump to cliamp radio immediately with loading indicator by Taha Sadough (@tahadx) (
d35e4e9) - remove extra playlist page for simplicity. the new playlist page is the playlist manager by Taha Sadough (@tahadx) (
e36a777) - test: make the new tests pass on Windows by Bjarne Oeverli (@bjarneo) (
b1a8848) - build(nix): update the Go vendor hash by Bjarne Oeverli (@bjarneo) (
d776878) - docs: add mac-notify to community plugins by David E. Barrera (@dbarrerap) (
026c1b5) - fix(playlist): read the LIST INFO tags of WAV files by Bjarne Oeverli (@bjarneo) (
0f42e20) - fix(view): wrap the too-small message to the terminal width by Bjarne Oeverli (@bjarneo) (
387b147) - fix(model): give Lua track events the decoded duration by Bjarne Oeverli (@bjarneo) (
2d1ce69) - fix(cli): keep zero position, volume and index in status --json by Bjarne Oeverli (@bjarneo) (
8150661) - fix(ipc): name a socket path that is too long by Bjarne Oeverli (@bjarneo) (
b38d1be) - fix(ipc): reject unknown shuffle, repeat and mono values by Bjarne Oeverli (@bjarneo) (
c930bfc) - fix(cli): send an absolute path from cliamp queue by Bjarne Oeverli (@bjarneo) (
96a095b) - fix(lyrics): treat a NetEase reply with no song list as not found by Bjarne Oeverli (@bjarneo) (
9321e91) - docs(claude): state that tests read the docs and the example config by Bjarne Oeverli (@bjarneo) (
4de3ae7) - docs(claude): isolate HOME only for the cliamp binary by Bjarne Oeverli (@bjarneo) (
b5c552e) - docs(claude): list the platform file suffixes that the tree uses by Bjarne Oeverli (@bjarneo) (
81b8cbf) - docs(keys): name SoundCloud and Yandex Music as Ctrl+F providers by Bjarne Oeverli (@bjarneo) (
12b7e2a) - docs(headless): link the Hotkeys section by its real anchor by Bjarne Oeverli (@bjarneo) (
531bd1f) - docs(headless): state that theme list and vis list still work by Bjarne Oeverli (@bjarneo) (
c6cee64) - docs(config): list every EQ preset, visualizer and provider by Bjarne Oeverli (@bjarneo) (
2b174df) - fix(cli): show true as the --expand-playlist default in help by Bjarne Oeverli (@bjarneo) (
8064f63) - fix(cli): accept --version without a version from ldflags by Bjarne Oeverli (@bjarneo) (
65bd67b) - docs(cli): state that the sample rate default is 0 for auto by Bjarne Oeverli (@bjarneo) (
3c18938) - build: format untracked Go files and skip deleted ones by Bjarne Oeverli (@bjarneo) (
3454024) - ci: run the test suite once and list the skips from its log by Bjarne Oeverli (@bjarneo) (
f28548f) - docs(headless): name the servers that get playback reports by Bjarne Oeverli (@bjarneo) (
831d2c9) - docs(plugins): state that cliamp.player.seek seeks relative by Bjarne Oeverli (@bjarneo) (
f07020e) - docs(plugins): name only free keys in the p:bind examples by Bjarne Oeverli (@bjarneo) (
a33d018) - refactor(favorites): delete the unused Favorite, Remove and Clear by Bjarne Oeverli (@bjarneo) (
072918a) - fix(history): take realtime and restricted from a provider replay by Bjarne Oeverli (@bjarneo) (
27c3095) - docs(cli): state that history --limit only limits the output by Bjarne Oeverli (@bjarneo) (
4e09cba) - fix(resolve): take an existing path literally before a glob by Bjarne Oeverli (@bjarneo) (
3cfe93e) - test(netdiag): build the wrapped dial error the way Streaming does by Bjarne Oeverli (@bjarneo) (
bd95097) - fix(local): leave the hidden Favorites.toml out of search results by Bjarne Oeverli (@bjarneo) (
2a77cd8) - fix(radio): lock and reload the pins file for each toggle by Bjarne Oeverli (@bjarneo) (
6b76878) - docs(httpclient): state where stream and API proxy rules differ by Bjarne Oeverli (@bjarneo) (
3f8c925) - fix(plex): stop paging when the server ignores the start offset by Bjarne Oeverli (@bjarneo) (
eb608d1) - fix(local): read no directory tags while the playlist lock is held by Bjarne Oeverli (@bjarneo) (
877fa4f) - fix(local): keep duplicate tracks when a playlist is saved by Bjarne Oeverli (@bjarneo) (
5450f73) - fix(upgrade): restart the idle timer when the headers arrive by Bjarne Oeverli (@bjarneo) (
ef2b31e) - fix(upgrade): read the release list up to 16 MiB by Bjarne Oeverli (@bjarneo) (
e4072cf) - fix(upgrade): never downgrade with --prerelease by Bjarne Oeverli (@bjarneo) (
8852129) - docs(providers): drop stale stream.go and webAPIOnce lock comments by Bjarne Oeverli (@bjarneo) (
6b34c36) - fix(spotify): ask for sign-in when the Web API rejects the token by Bjarne Oeverli (@bjarneo) (
effb5d2) - fix(qobuz,tidal): keep a newer client when an old request fails auth by Bjarne Oeverli (@bjarneo) (
b21eba3) - refactor(netease): take the yt-dlp install hint from internal/ytdlp by Bjarne Oeverli (@bjarneo) (
aa683c7) - fix(ytmusic): keep a browser sign-in when a silent check runs by Bjarne Oeverli (@bjarneo) (
1c3bcd1) - docs(config): match the setup and bool docs to the code by Bjarne Oeverli (@bjarneo) (
e0c39ec) - fix(config): ignore NaN and infinite numbers in config.toml by Bjarne Oeverli (@bjarneo) (
3937be2) - fix(config): keep quoted commas and read a # right after a close by Bjarne Oeverli (@bjarneo) (
0cebfa6) - fix(config): lock config.toml for each read, edit and write by Bjarne Oeverli (@bjarneo) (
7e70ce4) - fix(config): add a new top-level key after the last top-level key by Bjarne Oeverli (@bjarneo) (
763e0aa) - fix(config): save every line of a duplicate top-level key by Bjarne Oeverli (@bjarneo) (
2354eda) - fix(playlist): stop enrich of a virtual playlist before the probes by Bjarne Oeverli (@bjarneo) (
f2945b2) - test(playlist): cover the enrich probe and merge rules by Bjarne Oeverli (@bjarneo) (
7fd5553) - fix(playlist): let doctor --fix skip the virtual Favorites playlist by Bjarne Oeverli (@bjarneo) (
e13e104) - fix(config): read the plugin keys that cliamp uses with the value rules by Bjarne Oeverli (@bjarneo) (
0f97463) - fix(setup): check a $NAME url through its variable by Bjarne Oeverli (@bjarneo) (
2007d8c) - fix(setup): save the NetEase user_id that the probe finds by Bjarne Oeverli (@bjarneo) (
a4abfb3) - fix(luaplugin): load plugins only with the approved permissions by Bjarne Oeverli (@bjarneo) (
15b2742) - fix(luaplugin): refuse a second plugin.register call by Bjarne Oeverli (@bjarneo) (
1b47a5c) - fix(pluginmgr): approve only the plugin content that trust showed by Bjarne Oeverli (@bjarneo) (
b4b0b5b) - fix(luaplugin): stop plugin commands at the start of Close by Bjarne Oeverli (@bjarneo) (
bd5d114) - fix(luaplugin): stop exec child processes that hold the output pipes by Bjarne Oeverli (@bjarneo) (
17d8460) - fix(luaplugin): end blocking plugin APIs with the call time limit by Bjarne Oeverli (@bjarneo) (
2425852) - fix(luaplugin): run coroutines under the call that resumes them by Bjarne Oeverli (@bjarneo) (
c2d6fe0) - fix(pluginmgr): drop control characters from the plugin list by Bjarne Oeverli (@bjarneo) (
56a47f8) - fix(luaplugin): send plugin print output to plugins.log by Bjarne Oeverli (@bjarneo) (
8df8303) - fix(luaplugin): read visualizer objects under the plugin lock by Bjarne Oeverli (@bjarneo) (
fc625da) - fix(luaplugin): reject store values that JSON cannot hold by Bjarne Oeverli (@bjarneo) (
928710c) - fix(luaplugin): skip player controls until the provider is set by Bjarne Oeverli (@bjarneo) (
b274e7b) - fix(luaplugin): keep plugins from writing the IPC PID file by Bjarne Oeverli (@bjarneo) (
9ead3c6) - fix(luaplugin): report the repeat mode in the case the provider uses by Bjarne Oeverli (@bjarneo) (
9696dec) - fix(mediactl): keep the MPRIS track id when only the length changes by Bjarne Oeverli (@bjarneo) (
e6535b7) - fix(mediactl): stop an MPRIS update panic after the bus drops by Bjarne Oeverli (@bjarneo) (
23c66b7) - fix(player): mark an ICY file finite before the prefetch reads it by Bjarne Oeverli (@bjarneo) (
d7f1257) - fix(player): decode yt-dlp audio off the speaker callback by Bjarne Oeverli (@bjarneo) (
70e5f79) - fix(player): end a cleanly finished prefetch stream with a short read by Bjarne Oeverli (@bjarneo) (
bcb4629) - fix(player): let Stop and a skip interrupt a stalled yt-dlp read by Bjarne Oeverli (@bjarneo) (
245e72e) - fix(player): skip the yt-dlp seek mute after a track change by Bjarne Oeverli (@bjarneo) (
98c18df) - fix(player): close the dropped preload off the prepared seek path by Bjarne Oeverli (@bjarneo) (
c4973c0) - docs(player): fix the ClearPreload and PlayAt comments by Bjarne Oeverli (@bjarneo) (
d2cc938) - fix(theme): skip a user theme named default by Bjarne Oeverli (@bjarneo) (
272c394) - fix(theme): skip theme files that lack any of the six colors by Bjarne Oeverli (@bjarneo) (
4a993cf) - test(ui): pin 1-row and wide visualizer frames in the golden hashes by Bjarne Oeverli (@bjarneo) (
ced8102) - fix(ui): keep Lua visualizer names on each Visualizer by Bjarne Oeverli (@bjarneo) (
0741ae1) - fix(model): init a Lua visualizer with the real terminal size by Bjarne Oeverli (@bjarneo) (
b726534) - refactor(model): keep the frame padding on the Model by Bjarne Oeverli (@bjarneo) (
a475f92) - docs(cli): list Stereo with the modes that already tick at 60 FPS by Bjarne Oeverli (@bjarneo) (
ba4f02b) - refactor(ui): drop the unused Visualizer.SampleBuf by Bjarne Oeverli (@bjarneo) (
fbb1ee0) - style(model): tidy the undo comment and a queue edit test by Bjarne Oeverli (@bjarneo) (
b6c14e9) - fix(model): refresh Recently Played views after IPC history.clear by Bjarne Oeverli (@bjarneo) (
b1d4ab6) - docs(headless): start the scripted queue with cliamp play by Bjarne Oeverli (@bjarneo) (
3964f65) - fix(model): re-arm the preload through one guarded helper by Bjarne Oeverli (@bjarneo) (
56ca97b) - fix: wait for queued playback reports at exit by Bjarne Oeverli (@bjarneo) (
2b4eea6) - fix(model): scrobble the track that plays at quit by Bjarne Oeverli (@bjarneo) (
748f358) - fix(model): drop a pending seek on stop by Bjarne Oeverli (@bjarneo) (
4846637) - fix(model): skip Recently Played as the loaded list of the manager by Bjarne Oeverli (@bjarneo) (
caaf921) - fix: keep the order of V2 jobs sent back to back by Bjarne Oeverli (@bjarneo) (
6e02e58) - fix(model): publish runtime state when a buffering stream starts by Bjarne Oeverli (@bjarneo) (
1f55680) - fix(model): refuse a queue move when its save fails by Bjarne Oeverli (@bjarneo) (
10457a2) - fix(model): keep a detached track playing on a row removal by Bjarne Oeverli (@bjarneo) (
943688e) - fix(model): go back a track on previous during a rewind by Bjarne Oeverli (@bjarneo) (
841bd95) - fix(model): reset the playlist cursor on IPC queue.clear by Bjarne Oeverli (@bjarneo) (
d52238d) - fix(model): end the radio batch on every queue replace by Bjarne Oeverli (@bjarneo) (
a9db72b) - fix(model): follow an IPC rename of the loaded playlist by Bjarne Oeverli (@bjarneo) (
ccde93b) - fix(model): undo a saved removal with one locked insert by Bjarne Oeverli (@bjarneo) (
072181f) - fix(local): keep a track saved between two tracks in place by Bjarne Oeverli (@bjarneo) (
306c8b9) - fix(model): refuse Ctrl+Z after a later queue edit by Bjarne Oeverli (@bjarneo) (
f70f85b) - refactor(model): drop isOverlayActive from the tick decisions by Bjarne Oeverli (@bjarneo) (
2abe115) - docs(model): describe what Update adds around update by Bjarne Oeverli (@bjarneo) (
7b5982a) - fix(model): let the top overlay decide the content-first layout by Bjarne Oeverli (@bjarneo) (
b3e34dc) - fix(model): block undo and the keymap on a too-small screen by Bjarne Oeverli (@bjarneo) (
1774461) - fix(model): send input to the provider filter only with its focus by Bjarne Oeverli (@bjarneo) (
91b9b2c) - fix(model): let the browser replace prompt own the keys by Bjarne Oeverli (@bjarneo) (
79dd60c) - refactor(model): drop the plugin forwards of F and ctrl+r by Bjarne Oeverli (@bjarneo) (
acac52c) - fix(luaplugin): refuse reserved keys in the top-level chunk of a plugin by Bjarne Oeverli (@bjarneo) (
82fa231) - fix(model): drop a feed or file browser replace that lands late by Bjarne Oeverli (@bjarneo) (
f39bae5) - fix(model): unpause a yt-dlp reconnect only on the same track by Bjarne Oeverli (@bjarneo) (
0966fae) - test(main): cover the job events of the V2 server by Bjarne Oeverli (@bjarneo) (
81bf955) - fix(main): save the exit state on signals in the TUI and on SIGHUP by Bjarne Oeverli (@bjarneo) (
0a1d3b4) - fix(main): stop a second daemon before it loads the plugins by Bjarne Oeverli (@bjarneo) (
6d4b2e8) - test(main): keep the test socket path short on macOS by Bjarne Oeverli (@bjarneo) (
27b9ac7) - fix(main): print the IPC start error with one ipc prefix by Bjarne Oeverli (@bjarneo) (
1a25782) - test(main): cover the V2 dispatcher, plugin jobs and startIPC by Bjarne Oeverli (@bjarneo) (
e663d6e) - refactor(main): name the V2 dispatcher for both modes by Bjarne Oeverli (@bjarneo) (
a4c6b3a) - docs(provider): wire the creds command into buildApp by Bjarne Oeverli (@bjarneo) (
7c825dc) - docs(agents): isolate HOME and XDG dirs when running a test binary by Bjarne Oeverli (@bjarneo) (
5c7dd2b) - docs(agents): complete the IPC operation steps and ui/model table by Bjarne Oeverli (@bjarneo) (
2252880) - docs(provider): keep every buffered matcher and name the cookie hook by Bjarne Oeverli (@bjarneo) (
5f9a800) - docs: add remote control and headless mode to the README and site by Bjarne Oeverli (@bjarneo) (
ede2cee) - docs(provider): list every place that a new provider touches by Bjarne Oeverli (@bjarneo) (
a5b9503) - docs(agents): map the packages, runtime and IPC of the new code by Bjarne Oeverli (@bjarneo) (
d8e9eb7) - build(nix): keep local media and secrets out of the package source by Bjarne Oeverli (@bjarneo) (
cb889bf) - ci: list the skipped tests after make ci by Bjarne Oeverli (@bjarneo) (
840f7ec) - style(config): re-wrap the save doc comment by Bjarne Oeverli (@bjarneo) (
c1e5248) - docs(mediactl): describe clamped and NaN MPRIS volume writes by Bjarne Oeverli (@bjarneo) (
17b52c2) - test(model): isolate the config dir in the quick switch test by Bjarne Oeverli (@bjarneo) (
97c6e80) - fix(mediactl): survive a lost bus in the volume republish by Bjarne Oeverli (@bjarneo) (
e906230) - refactor(cmd): draw the radio globe from its own palette by Bjarne Oeverli (@bjarneo) (
61693dd) - fix(config): keep a saved key beside the top-level keys by Bjarne Oeverli (@bjarneo) (
0d3d8bc) - docs(yandex): name registerPlayerHooks as the resolver owner by Bjarne Oeverli (@bjarneo) (
87c170b) - fix: keep the newest provider sign-in cancelable by Bjarne Oeverli (@bjarneo) (
5d02302) - docs(model): name buildProviders in the provider key comment by Bjarne Oeverli (@bjarneo) (
e586070) - refactor(tracksave): delete Save and resolve.DownloadYTDL by Bjarne Oeverli (@bjarneo) (
4f1955f) - fix(model): stop an IPC save download on job.cancel by Bjarne Oeverli (@bjarneo) (
23dbfa6) - fix(model): return from overlays after every provider quick switch by Bjarne Oeverli (@bjarneo) (
d997bb5) - fix(model): let the manager delete prompt own provider shortcuts by Bjarne Oeverli (@bjarneo) (
8047ad8) - docs(luaplugin): name lua_wiring.go in the provider comments by Bjarne Oeverli (@bjarneo) (
a024eba) - docs(plugins): bind an unreserved key in the p:bind example by Bjarne Oeverli (@bjarneo) (
a19d0d2) - fix(pluginmgr): check the trust manifest before install and remove by Bjarne Oeverli (@bjarneo) (
95d28a7) - refactor(player): mark resolved Qobuz and Tidal sources as buffered by Bjarne Oeverli (@bjarneo) (
219266a) - fix(mediactl): republish Volume after a clamped client Set by Bjarne Oeverli (@bjarneo) (
35d12c3) - fix(mediactl): reject a NaN MPRIS volume by Bjarne Oeverli (@bjarneo) (
e0a8f97) - fix(player): ignore NaN volume, speed and EQ values by Bjarne Oeverli (@bjarneo) (
bfb9db9) - build: run the test suite once in the ci target by Bjarne Oeverli (@bjarneo) (
b9fbdd3) - test(luaplugin): guard the plugin event count on the site by Bjarne Oeverli (@bjarneo) (
384588f) - test(theme): guard the built-in theme count on the site by Bjarne Oeverli (@bjarneo) (
8816def) - test(model): guard the EQ preset count on the site by Bjarne Oeverli (@bjarneo) (
488a219) - test(ui): guard the visualizer counts on the site by Bjarne Oeverli (@bjarneo) (
6ed5b11) - test(model): start changeEngine at its offset through the shared fake by Bjarne Oeverli (@bjarneo) (
d49d055) - fix(model): skip the resume seek when a late start is past the hint by Bjarne Oeverli (@bjarneo) (
0b498a5) - test(model): cover the resume seek after a failed start seek by Bjarne Oeverli (@bjarneo) (
a9ec29c) - fix(cmd): report restricted tracks in cliamp history --json by Bjarne Oeverli (@bjarneo) (
9e705f2) - fix(model): keep the gated hint off a failed local ffmpeg start by Bjarne Oeverli (@bjarneo) (
eafb759) - docs(model): say what cancels an IPC url.load resolve by Bjarne Oeverli (@bjarneo) (
c7c2ce6) - fix(model): skip the resume seek when playback starts at the hint by Bjarne Oeverli (@bjarneo) (
66cb80f) - fix(model): skip the exit resume of any live stream by Bjarne Oeverli (@bjarneo) (
3a8f869) - refactor(resolve): take a plain browser string in the batch resolvers by Bjarne Oeverli (@bjarneo) (
874d84e) - fix(model): stop an IPC url.load when its client disconnects by Bjarne Oeverli (@bjarneo) (
d8fc413) - refactor(model): check the batch host with playlist.IsYouTubeMusicURL by Bjarne Oeverli (@bjarneo) (
559db16) - refactor(playlist): mark restricted tracks with Track.Restricted by Bjarne Oeverli (@bjarneo) (
129384e) - refactor: move the yt-dlp installer next to the install prompt by Bjarne Oeverli (@bjarneo) (
6faa0a8) - fix(player): close the dropped preload async after a native seek by Bjarne Oeverli (@bjarneo) (
b50ff61) - refactor(player): share Err, Len and Position by the pipe streamers by Bjarne Oeverli (@bjarneo) (
c145325) - refactor(player): share one timed peek by the ffmpeg and yt-dlp waits by Bjarne Oeverli (@bjarneo) (
0da9b91) - fix(player): write ctrl under the speaker lock on the first start by Bjarne Oeverli (@bjarneo) (
5747a3a) - refactor(player): share one position and duration rule by Bjarne Oeverli (@bjarneo) (
4b71036) - test(model): share one engine fake across the model tests by Bjarne Oeverli (@bjarneo) (
0bb36eb) - fix(model): start local ffmpeg formats off the Update goroutine by Bjarne Oeverli (@bjarneo) (
bbc3b4b) - refactor(player): route yt-dlp pages inside the player by Bjarne Oeverli (@bjarneo) (
3e994c3) - refactor(player): add IsLiveStream to Engine by Bjarne Oeverli (@bjarneo) (
c692147) - refactor(player): drop IsStreamSeek from Engine by Bjarne Oeverli (@bjarneo) (
7afa814) - refactor(player): send httpclient.UserAgent on stream requests by Bjarne Oeverli (@bjarneo) (
9483c3b) - refactor(radio): cap every body read with httpclient.ReadBody by Bjarne Oeverli (@bjarneo) (
1cca26c) - refactor(model): check the batch host with playlist.NormalizeHost by Bjarne Oeverli (@bjarneo) (
9de146e) - refactor(model): pick the save download with tracksave.NeedsDownload by Bjarne Oeverli (@bjarneo) (
1a69825) - fix(model): fit vis picker scroll to the rows after the apply by Bjarne Oeverli (@bjarneo) (
2ce36ba) - refactor(model): share one header-aware scroll fit by three lists by Bjarne Oeverli (@bjarneo) (
467993e) - refactor(model): draw the list overlays from one shownRows view by Bjarne Oeverli (@bjarneo) (
d50c408) - refactor(model): group the jump, URL, info and provider pane fields by Bjarne Oeverli (@bjarneo) (
9c976b1) - refactor(model): rename spotSearch to searchOverlay by Bjarne Oeverli (@bjarneo) (
77df780) - refactor(model): lay out the frame in Update, not in View by Bjarne Oeverli (@bjarneo) (
9453e4f) - refactor(ui): drop the PanelWidth and FrameStyle globals by Bjarne Oeverli (@bjarneo) (
0498631) - refactor(model): read the panel width from the layout, not a global by Bjarne Oeverli (@bjarneo) (
3b56463) - refactor(model): split the tick body into one method per job by Bjarne Oeverli (@bjarneo) (
f5fbf89) - fix(model): share one next-track rule by skip, drain and gapless by Bjarne Oeverli (@bjarneo) (
c039f5b) - refactor(model): move list cursor keys into stepListCursor by Bjarne Oeverli (@bjarneo) (
3eb469c) - refactor(model): share one filterList by four list overlays by Bjarne Oeverli (@bjarneo) (
b23e01f) - refactor(model): call effectivePlaylistVisible without wrappers by Bjarne Oeverli (@bjarneo) (
21ce321) - fix(ui): redraw ClassicLED at its declared 30 FPS by Bjarne Oeverli (@bjarneo) (
e433955) - refactor(model): keep every derived style in styles.go by Bjarne Oeverli (@bjarneo) (
870247b) - test(model): prove that ctrl+z runs the playlist undo by Bjarne Oeverli (@bjarneo) (
5a2c808) - test(model): walk every main key path function in the drift test by Bjarne Oeverli (@bjarneo) (
37bcdf4) - docs(keybindings): give N its own row in the provider browser by Bjarne Oeverli (@bjarneo) (
043d16f) - test(model): check the ctrl+r plugin forward in the playlist view by Bjarne Oeverli (@bjarneo) (
018f9e5) - test(model): count provider shortcuts in the overlay drift test by Bjarne Oeverli (@bjarneo) (
781c69b) - docs(yt-dlp): name Ctrl+S as the key that saves a track by Bjarne Oeverli (@bjarneo) (
7e1557a) - docs(keybindings): list the provider shortcuts each view takes by Bjarne Oeverli (@bjarneo) (
ae8e163) - test(model): check overlay key handlers against the registry by Bjarne Oeverli (@bjarneo) (
572844b) - test(model): walk the main key path with go/ast by Bjarne Oeverli (@bjarneo) (
c2001e7) - refactor(model): split handleKey by the owner of the key by Bjarne Oeverli (@bjarneo) (
dad4711) - refactor(model): share the ctrl+r provider refresh by Bjarne Oeverli (@bjarneo) (
f9bddc5) - refactor(model): look up provider shortcuts in one place by Bjarne Oeverli (@bjarneo) (
1973519) - fix(model): show provider hints on the minimal tier by Bjarne Oeverli (@bjarneo) (
68c4138) - test(model): check that overlayStack holds each screen once by Bjarne Oeverli (@bjarneo) (
2c5d89d) - docs(model): say why the overlay order still matters by Bjarne Oeverli (@bjarneo) (
7cfe24d) - refactor(model): drop unreachable ctrl+c and ctrl+k clauses by Bjarne Oeverli (@bjarneo) (
30483f0) - fix(model): show the YouTube search over the nav browser by Bjarne Oeverli (@bjarneo) (
913286b) - refactor(model): resolve the command mode in one place by Bjarne Oeverli (@bjarneo) (
c1d3e68) - refactor(model): derive the overlay order from one table by Bjarne Oeverli (@bjarneo) (
fca4817) - refactor(model): drop stale comment in handleNavAlbumsLoaded by Bjarne Oeverli (@bjarneo) (
68ff7f6) - refactor(model): move the V2 response body to ipc_runtime.go by Bjarne Oeverli (@bjarneo) (
61428eb) - refactor(model): move queue load message bodies to update_load.go by Bjarne Oeverli (@bjarneo) (
66e739a) - refactor(model): move search message bodies to update_search.go by Bjarne Oeverli (@bjarneo) (
1352ae0) - refactor(model): move nav browser message bodies to update_nav.go by Bjarne Oeverli (@bjarneo) (
f42862e) - refactor(model): move provider message bodies to update_provider.go by Bjarne Oeverli (@bjarneo) (
3e2c5cf) - refactor(model): move playback message bodies to update_playback.go by Bjarne Oeverli (@bjarneo) (
0cba6b4) - refactor(model): move the tick body to handleTick in tick.go by Bjarne Oeverli (@bjarneo) (
9020289) - refactor(model): move queue overlay keys to keys_queue.go by Bjarne Oeverli (@bjarneo) (
0049aa9) - refactor(model): move picker keys to keys_pickers.go by Bjarne Oeverli (@bjarneo) (
37e5885) - refactor(model): move search keys to keys_search.go by Bjarne Oeverli (@bjarneo) (
e895484) - refactor(model): move the playlist order writer to queue_ops.go by Bjarne Oeverli (@bjarneo) (
e8bfd1d) - refactor(model): move playlist manager keys to keys_plmgr.go by Bjarne Oeverli (@bjarneo) (
3f993d5) - fix(model): report the play before a rewind only when it lands by Bjarne Oeverli (@bjarneo) (
ec353ff) - fix(model): drop a waiting progress report that a newer one replaces by Bjarne Oeverli (@bjarneo) (
46391c5) - fix(model): start a rewind replay only when the rewind lands by Bjarne Oeverli (@bjarneo) (
06b0bb0) - test(model): cover each stop path that scrobbles the left track by Bjarne Oeverli (@bjarneo) (
8a9ffc8) - refactor(model): find a capable provider through one findCapable by Bjarne Oeverli (@bjarneo) (
2d3ac97) - fix(lyrics): report an oversized lyrics response as too large by Bjarne Oeverli (@bjarneo) (
c588cc1) - refactor(model): notify the media controls once per playback change by Bjarne Oeverli (@bjarneo) (
c0ef619) - fix(model): scrobble a left track through one leaveTrack by Bjarne Oeverli (@bjarneo) (
21b8c0a) - fix(model): send playback reports to providers in order by Bjarne Oeverli (@bjarneo) (
ba061c6) - refactor(lyrics): look up lyrics in one order with lyrics.Lookup by Bjarne Oeverli (@bjarneo) (
9b2f742) - refactor(model): split ICY stream titles with one rule by Bjarne Oeverli (@bjarneo) (
4e9abae) - fix(model): refuse a dir track removal only for a mirrored playlist by Bjarne Oeverli (@bjarneo) (
eda60fc) - fix(model): record a removal undo only for the x key by Bjarne Oeverli (@bjarneo) (
14ae2e5) - docs(site): say that a Lua queue move under shuffle changes nothing by Bjarne Oeverli (@bjarneo) (
3958541) - test(model): cover the immediate preload re-arm of each queue edit by Bjarne Oeverli (@bjarneo) (
f3372ee) - fix(model): play a queue row through one playIndex verb by Bjarne Oeverli (@bjarneo) (
a91425e) - fix(model): reload only the Local pane after a history or favorite write by Bjarne Oeverli (@bjarneo) (
c863c41) - fix(model): apply one rule to key, IPC and Lua queue edits by Bjarne Oeverli (@bjarneo) (
912f979) - refactor(model): append to the queue through appendTracks by Bjarne Oeverli (@bjarneo) (
b48f615) - refactor(provider): add AddTracks for the batch writer fallback by Bjarne Oeverli (@bjarneo) (
05cc7d1) - refactor(model): route playback messages and V2 through the verbs by Bjarne Oeverli (@bjarneo) (
29f1faf) - refactor(model): route the keys through one verb per playback action by Bjarne Oeverli (@bjarneo) (
e1be098) - refactor(model): save config through the typed savers by Bjarne Oeverli (@bjarneo) (
25f9999) - fix(model): name a failed resume a track, not a show by Bjarne Oeverli (@bjarneo) (
35d459f) - refactor(model): keep the playlist updater seam inside ui/model by Bjarne Oeverli (@bjarneo) (
c7e9435) - refactor(model): drop the catalog fallback of the IPC provider search by Bjarne Oeverli (@bjarneo) (
adf85de) - docs(model): say that only old files reload resolver tracks as files by Bjarne Oeverli (@bjarneo) (
f59919a) - fix(model): resume a network stream seek off the Update goroutine by Bjarne Oeverli (@bjarneo) (
0746384) - feat(cmd): add provider_meta to cliamp history --json by Bjarne Oeverli (@bjarneo) (
6011b77) - fix(cmd): state the track-start rule in the empty history message by Bjarne Oeverli (@bjarneo) (
2bf622c) - test(model): prove the IPC radio search keeps the pane search by Bjarne Oeverli (@bjarneo) (
b7db676) - feat(radio): add SearchStations, a station search with no pane state by Bjarne Oeverli (@bjarneo) (
07775f5) - fix(model): keep other writers' changes on a queue or manager edit by Bjarne Oeverli (@bjarneo) (
9ff8c72) - fix(local): scan no directory while UpdatePlaylist holds the lock by Bjarne Oeverli (@bjarneo) (
a2ba51f) - docs(model): name buildProviders as the owner of the shared stores by Bjarne Oeverli (@bjarneo) (
d83bfff) - docs(model): name the picker lists of any searched provider by Bjarne Oeverli (@bjarneo) (
3f8674b) - fix: keep provider URI tracks off the Update goroutine after a reload by Bjarne Oeverli (@bjarneo) (
b9dbd22) - fix(model): keep the pane search on an IPC station search by Bjarne Oeverli (@bjarneo) (
58aa263) - feat(playlist): keep the album art URL in favorites and history by Bjarne Oeverli (@bjarneo) (
9c4d306) - refactor(playlist): delete the unused Playlist.ToggleBookmark by Bjarne Oeverli (@bjarneo) (
a09c831) - fix(local): run playlist read-modify-write under the playlist lock by Bjarne Oeverli (@bjarneo) (
0697686) - refactor(playlist): mark favorite rows in PlaylistInfo by Bjarne Oeverli (@bjarneo) (
54178ad) - refactor(model): find synced lyrics by provider capability by Bjarne Oeverli (@bjarneo) (
fa7b8c8) - refactor(local): move the Favorites.toml rename to startup by Bjarne Oeverli (@bjarneo) (
f76628c) - refactor: build the favorites and history stores once by Bjarne Oeverli (@bjarneo) (
6576ccb) - refactor(playlist): move the audio extension set out of player by Bjarne Oeverli (@bjarneo) (
5f0e226) - refactor(model): unexport playsLive by Bjarne Oeverli (@bjarneo) (
bef5d03) - fix(model): publish the plugin state before app.start by Bjarne Oeverli (@bjarneo) (
2e6bb79) - fix(lua): queue every plugin control instead of dropping it by Bjarne Oeverli (@bjarneo) (
a9590ab) - fix(ipc): mark only the active visualizer row in vis list by Bjarne Oeverli (@bjarneo) (
d88b832) - perf(model): build the Lua queue rows on the first read by Bjarne Oeverli (@bjarneo) (
01fc29b) - fix(model): publish the plugin state before each plugin event by Bjarne Oeverli (@bjarneo) (
bcae21e) - docs(site): name the init and destroy of Lua visualizers by Bjarne Oeverli (@bjarneo) (
df282d3) - fix(pluginmgr): list no plugin as trusted from a bad manifest by Bjarne Oeverli (@bjarneo) (
a7fe911) - refactor(model): hand Lua a loader that holds only the state store by Bjarne Oeverli (@bjarneo) (
3b0fa28) - docs(luaplugin): say how the Lua providers reach the Model by Bjarne Oeverli (@bjarneo) (
250b426) - docs(plugins): state what os.getenv and cliamp.fs can read by Bjarne Oeverli (@bjarneo) (
c06fbae) - refactor(luaplugin): build the plugin data write root with appdir by Bjarne Oeverli (@bjarneo) (
7d457fa) - fix(pluginmgr): explain a trust manifest that does not parse by Bjarne Oeverli (@bjarneo) (
868e807) - fix(ipc): list Lua visualizer modes in vis list by Bjarne Oeverli (@bjarneo) (
fcc7553) - fix(ui): keep built-in visualizer names from Lua plugins by Bjarne Oeverli (@bjarneo) (
340ec5b) - fix(ui): give Lua visualizers the smoothed spectrum bands by Bjarne Oeverli (@bjarneo) (
1b513c6) - fix(ui): run the init and destroy of Lua visualizers by Bjarne Oeverli (@bjarneo) (
82bdda4) - fix(luaplugin): let set_volume reach the volume_min floor by Bjarne Oeverli (@bjarneo) (
7b90446) - perf(model): build each plugin event only when a hook wants it by Bjarne Oeverli (@bjarneo) (
9e09c4b) - fix(lua): read plugin state from a snapshot that the Model publishes by Bjarne Oeverli (@bjarneo) (
a838047) - refactor(luaplugin): read the Lua track through one CurrentTrack by Bjarne Oeverli (@bjarneo) (
a806254) - fix(luaplugin): store the Lua providers in atomic pointers by Bjarne Oeverli (@bjarneo) (
863b61d) - fix(lua): queue plugin controls so a plugin never waits on prog.Send by Bjarne Oeverli (@bjarneo) (
3dd7b2e) - fix(lua): send volume, speed and mono controls to the Update loop by Bjarne Oeverli (@bjarneo) (
70a7966) - docs: point the agent guide at providers.go for provider setup by Bjarne Oeverli (@bjarneo) (
da28f71) - docs(url-scheme): say how long a cliamp:// link waits by Bjarne Oeverli (@bjarneo) (
a0fe9a7) - refactor: test the exit resume save through saveExitResume by Bjarne Oeverli (@bjarneo) (
0cd6073) - test: cover the resume saver of Jellyfin and Emby servers by Bjarne Oeverli (@bjarneo) (
5a05900) - docs: say what providerSet finds without provider code by Bjarne Oeverli (@bjarneo) (
3b6b161) - docs(site): list YouTube Music in the yt-dlp install note by Bjarne Oeverli (@bjarneo) (
498c639) - test: move the built-in radio URL test into external/radio by Bjarne Oeverli (@bjarneo) (
c99967d) - refactor: share one builder for the shuffle and mono commands by Bjarne Oeverli (@bjarneo) (
da7dcee) - fix: list the terminal colors theme in cliamp theme list by Bjarne Oeverli (@bjarneo) (
a681a4c) - refactor: put the V2 CLI client in ipc_client.go with a bounded wait by Bjarne Oeverli (@bjarneo) (
d408134) - refactor: split run() into setup helpers by Bjarne Oeverli (@bjarneo) (
759a39b) - feat: resume the Emby play context like Jellyfin by Bjarne Oeverli (@bjarneo) (
a275273) - refactor: give Navidrome and Lyrion the same config wiring by Bjarne Oeverli (@bjarneo) (
f0f3a75) - refactor: derive the --provider text from one key table by Bjarne Oeverli (@bjarneo) (
7343c3b) - fix: start without a local provider when no config dir exists by Bjarne Oeverli (@bjarneo) (
26b69ab) - refactor: build providers in providers.go by Bjarne Oeverli (@bjarneo) (
e386f50) - fix(ytmusic): close the shared base from every YouTube provider by Bjarne Oeverli (@bjarneo) (
057b122) - refactor(provider): move ProviderEntry to provider.Entry by Bjarne Oeverli (@bjarneo) (
ccdabfd) - fix(ui/model): call the model method before the return reads m by Bjarne Oeverli (@bjarneo) (
aa2f1f9) - docs: say that one failed remote argument drops all of them by Bjarne Oeverli (@bjarneo) (
9f14d95) - fix(ipc): pass the canonical read method to the runtime owner by Bjarne Oeverli (@bjarneo) (
f159c33) - docs: correct the save, vis and device notes for headless mode by Bjarne Oeverli (@bjarneo) (
d111776) - fix(ui/model): name the provider list of an IPC load in the snapshot by Bjarne Oeverli (@bjarneo) (
6a819bf) - test: send a real signal to the headless program by Bjarne Oeverli (@bjarneo) (
5d2e8b5) - docs(radio): state the result cap of SearchStations by Bjarne Oeverli (@bjarneo) (
c311eda) - docs(config): state which proxy variables ffmpeg reads by Bjarne Oeverli (@bjarneo) (
fe25e4f) - docs(config): limit the unquoted list item rule to string lists by Bjarne Oeverli (@bjarneo) (
32e034a) - fix(ytmusic): share only the transport with the Data API client by Bjarne Oeverli (@bjarneo) (
75d2e01) - test(providers): pin the body limit of Plex, Lyrion and Audiobookshelf by Bjarne Oeverli (@bjarneo) (
b04fb64) - refactor(tracksave): export NeedsDownload for the yt-dlp save check by Bjarne Oeverli (@bjarneo) (
eed2e97) - feat(playlist): mark favorites section rows with PlaylistInfo.Favorite by Bjarne Oeverli (@bjarneo) (
5ac2575) - fix: keep the headless visualizer in the layout by Bjarne Oeverli (@bjarneo) (
5d6cdca) - feat(radio): add SearchStations, a station search with no pane state by Bjarne Oeverli (@bjarneo) (
32ff5e4) - refactor: use theme.IsDefaultName for the theme saved at exit by Bjarne Oeverli (@bjarneo) (
5b97514) - docs: state the track-start history rule in the history help by Bjarne Oeverli (@bjarneo) (
67cd02c) - fix: cap the JSON bodies of radio, radiometa and lyrics requests by Bjarne Oeverli (@bjarneo) (
c9c3c08) - refactor(ui/model): delete the V2 aliases that nothing can reach by Bjarne Oeverli (@bjarneo) (
d3d5181) - docs(remote): state which provider_meta keys cliamp saves by Bjarne Oeverli (@bjarneo) (
7e9f383) - docs(readme): match the setup wizard text to docs/cli.md by Bjarne Oeverli (@bjarneo) (
a99ac61) - docs(yt-dlp): name Ctrl+S as the save key by Bjarne Oeverli (@bjarneo) (
f761a9e) - docs(ssh): state the HOST forms that --ssh accepts by Bjarne Oeverli (@bjarneo) (
071b15f) - docs(cli): add the --provider, --visualizer and --expand-playlist rows by Bjarne Oeverli (@bjarneo) (
7456013) - test(ipc): cover the runtime.status alias in the server test by Bjarne Oeverli (@bjarneo) (
2122869) - docs(site): list YouTube Music in the yt-dlp install note by Bjarne Oeverli (@bjarneo) (
957c95b) - refactor(ipc): move the request structs that ui/model uses into it by Bjarne Oeverli (@bjarneo) (
511665a) - docs: state which proxy variables cliamp reads by Bjarne Oeverli (@bjarneo) (
71ee85d) - fix(ytmusic): send YouTube Data API calls through the NewAPI transport by Bjarne Oeverli (@bjarneo) (
4823e91) - refactor(ui): drop the PanelWidth fallback of the visualizer width by Bjarne Oeverli (@bjarneo) (
b74be26) - feat: run headless mode on the Model and delete the daemon by Bjarne Oeverli (@bjarneo) (
a2732b2) - test(ui/model): drop an unused model value in a headless test by Bjarne Oeverli (@bjarneo) (
dbb1bed) - fix(lyrion): name the provider Lyrion in the UI by Bjarne Oeverli (@bjarneo) (
309e6af) - test(navidrome): test SaveAlbumSort with a fake config writer by Bjarne Oeverli (@bjarneo) (
2bbdf85) - fix(ui/model): log the tracks that fail to play by Bjarne Oeverli (@bjarneo) (
83a9c26) - feat(cmd): add provider_meta to cliamp history --json by Bjarne Oeverli (@bjarneo) (
a7f0395) - fix(cmd): state the track-start rule in the empty history message by Bjarne Oeverli (@bjarneo) (
ca1367c) - refactor(ytdlcookies): use playlist.NormalizeHost for cookie hosts by Bjarne Oeverli (@bjarneo) (
3c6be9a) - fix(pluginmgr): download plugins through httpclient.NewAPI by Bjarne Oeverli (@bjarneo) (
3e58eee) - fix(lyrics): send the shared cliamp User-Agent to LRCLIB by Bjarne Oeverli (@bjarneo) (
132a015) - fix(resolve): find #EXT-X-ENDLIST past the HLS read cap by Bjarne Oeverli (@bjarneo) (
18f20cc) - feat(resolve): add RemoteContext and DownloadYTDLContext by Bjarne Oeverli (@bjarneo) (
06428fe) - fix(resolve): cancel the feed sniff with the URLContext context by Bjarne Oeverli (@bjarneo) (
f64a52e) - fix(resolve): send feed, sniff and YouTube requests through NewAPI by Bjarne Oeverli (@bjarneo) (
4ad29b1) - test(ui/model): port the headless daemon scenarios to the Model by Bjarne Oeverli (@bjarneo) (
faa6fa4) - test(ytmusic): read the callback body in the sign-in retry test by Bjarne Oeverli (@bjarneo) (
dc19700) - fix(spotify): close callback connections after each response by Bjarne Oeverli (@bjarneo) (
2362401) - refactor(spotify): share the token lookup in Session.bearer by Bjarne Oeverli (@bjarneo) (
550f4b5) - refactor: keep one live-stream rule in ui/model by Bjarne Oeverli (@bjarneo) (
ff6a59f) - fix(ui/model): report the fields that headless mode reported by Bjarne Oeverli (@bjarneo) (
0e2f998) - fix(spotify): send Web API calls through httpclient.NewAPI by Bjarne Oeverli (@bjarneo) (
4e8fbb5) - test(spotify): give each test session its own Web API client by Bjarne Oeverli (@bjarneo) (
972d05e) - fix(ui/model): keep the resume position on a media-control quit by Bjarne Oeverli (@bjarneo) (
5a5e108) - test(qobuz): run scrapeCredentials and newClientSilent against httptest by Bjarne Oeverli (@bjarneo) (
99161d7) - feat(ui/model): add a headless mode to the Model by Bjarne Oeverli (@bjarneo) (
1721f69) - fix(providers): send streaming API calls through httpclient.NewAPI by Bjarne Oeverli (@bjarneo) (
fed05ec) - fix(config): accept a # comment after a bracketed list by Bjarne Oeverli (@bjarneo) (
85581ea) - test: fix 3 staticcheck findings in new tests by Bjarne Oeverli (@bjarneo) (
4adf202) - fix: state that /dev/null on stdin still shows the yt-dlp prompt by Bjarne Oeverli (@bjarneo) (
88fdbeb) - style(luaplugin): name queueVis in the Close queue comment by Bjarne Oeverli (@bjarneo) (
4401232) - docs(plugins): state that exec can write outside the fs write rules by Bjarne Oeverli (@bjarneo) (
2b205fe) - fix(luaplugin): name the recovery step for a bad trust manifest by Bjarne Oeverli (@bjarneo) (
71ceb38) - fix(luaplugin): raise the render limit and log render timeouts apart by Bjarne Oeverli (@bjarneo) (
b1a71ac) - test(luaplugin): give renders that must succeed a 1 s limit by Bjarne Oeverli (@bjarneo) (
bc7839d) - fix(luaplugin): bound the queued event run in Close by Bjarne Oeverli (@bjarneo) (
99ad11a) - fix(luaplugin): stop running Lua calls in Close by Bjarne Oeverli (@bjarneo) (
7dc346b) - fix(luaplugin): queue visualizer init and destroy calls by Bjarne Oeverli (@bjarneo) (
4060dda) - fix: accept y and yes at the yt-dlp install prompt by Bjarne Oeverli (@bjarneo) (
c37035f) - refactor(ui/model): drop the unused IPC station search seam by Bjarne Oeverli (@bjarneo) (
6c3fe2a) - fix(ui/model): use the saved rule only for queue rows in IPC bookmark by Bjarne Oeverli (@bjarneo) (
9ef215f) - fix(ui/model): add up relative seeks during a yt-dlp seek by Bjarne Oeverli (@bjarneo) (
b470fab) - fix(ytmusic): keep token refresh working after a browser sign-in by Bjarne Oeverli (@bjarneo) (
85a0f12) - fix(ytmusic): close callback connections after each response by Bjarne Oeverli (@bjarneo) (
977dc2e) - fix(ytmusic): bound the silent sign-in with a 30 s timeout by Bjarne Oeverli (@bjarneo) (
92f1c89) - fix(embyapi): stop album paging when the server ignores startIndex by Bjarne Oeverli (@bjarneo) (
8aa54d7) - style(luaplugin): write two new comments as plain sentences by Bjarne Oeverli (@bjarneo) (
1870bf4) - docs(luaplugin): state that the plugin store is not secret by Bjarne Oeverli (@bjarneo) (
7fa95cd) - fix(httpclient): let net/http dial SOCKS5 proxies for API clients by Bjarne Oeverli (@bjarneo) (
31e8ca0) - fix(ytmusic): stop the sign-in wait when Google reports an error by Bjarne Oeverli (@bjarneo) (
d005613) - fix(luaplugin): reject an unknown type in plugin.register() by Bjarne Oeverli (@bjarneo) (
2354b96) - refactor(config): drop the YouTube Music fallback credentials hook by Bjarne Oeverli (@bjarneo) (
cf81f89) - fix(luaplugin): fold path case with Unicode rules in the write check by Bjarne Oeverli (@bjarneo) (
aed6cd8) - docs(cli): list the Qobuz, Tidal and YouTube Music reset commands by Bjarne Oeverli (@bjarneo) (
bfc9714) - fix(ui): start source resolver tracks off the Update goroutine by Bjarne Oeverli (@bjarneo) (
ff6c062) - test(luaplugin): keep the write rule test home in the temp dir by Bjarne Oeverli (@bjarneo) (
8ae96e7) - fix(luaplugin): drain exec output after a line longer than 1 MiB by Bjarne Oeverli (@bjarneo) (
e24c69d) - fix(luaplugin): never block the UI goroutine in RenderVis by Bjarne Oeverli (@bjarneo) (
a019827) - fix(luaplugin): bound the top-level chunk of a plugin at load by Bjarne Oeverli (@bjarneo) (
c1819a1) - fix(luaplugin): log callback errors only to plugins.log by Bjarne Oeverli (@bjarneo) (
1c8cff2) - fix: ask before a yt-dlp install only in an interactive start by Bjarne Oeverli (@bjarneo) (
414fc61) - test(ui/model): check the EQ save of the IPC settings table by Bjarne Oeverli (@bjarneo) (
d613f10) - fix(ui/model): search stations over IPC without the pane search state by Bjarne Oeverli (@bjarneo) (
cd0eeb1) - fix(ui/model): filter picker targets only through PlaylistTargetFilter by Bjarne Oeverli (@bjarneo) (
0d91304) - feat(config): add typed save methods to SaveFunc by Bjarne Oeverli (@bjarneo) (
39247bc) - refactor(ui/model): identify Local and Radio by provider key by Bjarne Oeverli (@bjarneo) (
bfd527d) - docs(themes): show the real theme skip log line by Bjarne Oeverli (@bjarneo) (
b829639) - 206 older commits are not listed. The full changelog link below shows all commits.
Checksums (SHA256)
836d0ed3d46a39ea0ff75b17738e77c2652c03fbc46aefb78110cb6664a41ee6 cliamp-darwin-amd64
f12a36efe27d8eaaf1ab489be2270850bea4a0f63f694cc1688693bf13e256b4 cliamp-darwin-arm64
2ee17d8f613d9dd23d124b8f5580111610f5aa396b20f2818e388f7b7a227152 cliamp-linux-amd64
4e686e9b5188030bd3382c7fac997077bbdff8953fbab0003c49874b5f9ea1fc cliamp-linux-arm64
7a8dee25e6b3b1ae20ce5f1d656decb0d5eb128201650f626c7ce772bf070811 cliamp-windows-amd64.exe
2f98eb4f968d603dadf0d68ef50a28104f2b7d7a0d01a55a49547bf9ba91dbcb cliamp-windows-amd64.zip
Full Changelog: v2.3.0...v2.4.0