ratatui 0.29 → 0.30 and ratatui-image 3 → 11 cannot be done independently, and neither can be done by Dependabot alone. Closing #75 and #72 in favour of this issue.
Why the two are locked together
ratatui-image links against ratatui and re-exports its widget traits, so the two crates must move in the same commit. Verified locally (toolchain 1.98.1, worktree off main):
ratatui 0.30.2 alone (#75) — every other file compiles; the sole error is the ratatui-image bridge:
error[E0277]: the trait bound `StatefulImage: StatefulWidget` is not satisfied
--> src/tui/widgets/album_art.rs:88:42
|
88 | frame.render_stateful_widget(image_widget, area, proto);
= note: `StatefulImage` implements similarly named trait `ratatui::widgets::StatefulWidget`,
but not `StatefulWidget`
ratatui-image 3.0.0 builds on ratatui 0.29, so its StatefulImage implements 0.29's StatefulWidget while Frame now wants ratatui-core 0.1's. ratatui-image 11 alone (#72) is the same failure mirrored — its lockfile keeps the app on ratatui 0.29 while pulling a second ratatui 0.30.0 in for ratatui-image.
What the upgrade actually requires
1. A new native system dependency (the biggest item)
ratatui-image 11 enables chafa-dyn by default, which shells out to pkg-config for libchafa >= 1.8.0:
error: failed to run custom build command for `ratatui-image v11.1.0`
Failed to find chafa via pkg-config. Install libchafa-dev or set PKG_CONFIG_PATH.
Needs version >= 1.8.0.
sonos-cli ships prebuilt binaries via cargo-dist to x86_64-unknown-linux-gnu, x86_64-apple-darwin, aarch64-apple-darwin and x86_64-pc-windows-msvc, plus a Homebrew tap. Taking a C dependency affects all four targets, the CI runner, and the Homebrew formula. Unless we actually want chafa, the dependency line needs:
ratatui-image = { version = "11", default-features = false, features = ["crossterm"] }
This is a deliberate packaging decision, which is exactly why it is not Dependabot's call.
2. Source changes in src/tui/widgets/album_art.rs
With default-features = false, two API breaks remain (both from the 11.0.0 release):
FontSize changed from a (u16, u16) tuple alias to struct FontSize { width, height }, so let (fw, fh) = p.font_size(); (line 57) no longer destructures.
StatefulImage::new(Option<..>) is gone; the type is now generic StatefulImage<T: ResizeEncodeRender> built via StatefulImage::default() with resize as a builder method, so StatefulImage::new(None) (line 87) fails with "this function takes 0 arguments but 1 argument was supplied".
Minimal patch that makes it build:
let fs = p.font_size();
let (fw, fh) = (fs.width, fs.height);
...
let image_widget = StatefulImage::default();
Also worth auditing while in here, from the 11.0.0 notes: Rect → Size across Picker::new_protocol(), ProtocolTrait::area() → size(), and Image no longer clips under Kitty/Halfblocks by default (Image::allow_clipping restores it). ImageSource and Resize::needs_resize were removed.
Verification already done
With default-features = false plus the two source fixes above, ratatui 0.30.2 + ratatui-image 11 builds clean and all 269 tests pass.
Render was checked for real, not just compiled: both binaries were driven headlessly through a pty with the terminal capability probes answered (DA1, DSR, CSI 16 t cell-size, kitty graphics APC _G), and the escape stream replayed into a 40x120 character grid. Baseline 0.29 and candidate 0.30.2 produce byte-identical grids — 550 non-blank cells and 4407 SGR-styled cells each, across the initial frame and after navigation keys. No blank-screen or layout regression.
So the upgrade is viable; it just needs a human to own the packaging decision and the source edits.
Sequencing — do this after the in-flight TUI work lands
Four feature branches are currently mid-flight against ratatui 0.29, totalling roughly 1,870 changed lines under src/tui/:
feat/tui-settings-view (13 files)
feat/tui-bottom-player-bar (12 files, including widgets/album_art.rs)
feat/tui-enhanced-speaker-list (6 files)
feat/tui-drop-zone-mode (5 files)
All four touch src/tui/types.rs, which holds the StatefulProtocol field. Landing a breaking render-API bump now would force all four to rebase across it simultaneously. Recommend letting them merge first, then doing this upgrade as one focused PR.
Suggested checklist
ratatui0.29 → 0.30 andratatui-image3 → 11 cannot be done independently, and neither can be done by Dependabot alone. Closing #75 and #72 in favour of this issue.Why the two are locked together
ratatui-imagelinks againstratatuiand re-exports its widget traits, so the two crates must move in the same commit. Verified locally (toolchain 1.98.1, worktree offmain):ratatui0.30.2 alone (#75) — every other file compiles; the sole error is theratatui-imagebridge:ratatui-image3.0.0 builds onratatui0.29, so itsStatefulImageimplements 0.29'sStatefulWidgetwhileFramenow wantsratatui-core0.1's.ratatui-image11 alone (#72) is the same failure mirrored — its lockfile keeps the app onratatui0.29 while pulling a secondratatui0.30.0 in forratatui-image.What the upgrade actually requires
1. A new native system dependency (the biggest item)
ratatui-image11 enableschafa-dynby default, which shells out topkg-configfor libchafa >= 1.8.0:sonos-cliships prebuilt binaries via cargo-dist tox86_64-unknown-linux-gnu,x86_64-apple-darwin,aarch64-apple-darwinandx86_64-pc-windows-msvc, plus a Homebrew tap. Taking a C dependency affects all four targets, the CI runner, and the Homebrew formula. Unless we actually want chafa, the dependency line needs:This is a deliberate packaging decision, which is exactly why it is not Dependabot's call.
2. Source changes in
src/tui/widgets/album_art.rsWith
default-features = false, two API breaks remain (both from the 11.0.0 release):FontSizechanged from a(u16, u16)tuple alias tostruct FontSize { width, height }, solet (fw, fh) = p.font_size();(line 57) no longer destructures.StatefulImage::new(Option<..>)is gone; the type is now genericStatefulImage<T: ResizeEncodeRender>built viaStatefulImage::default()with resize as a builder method, soStatefulImage::new(None)(line 87) fails with "this function takes 0 arguments but 1 argument was supplied".Minimal patch that makes it build:
Also worth auditing while in here, from the 11.0.0 notes:
Rect→SizeacrossPicker::new_protocol(),ProtocolTrait::area()→size(), andImageno longer clips under Kitty/Halfblocks by default (Image::allow_clippingrestores it).ImageSourceandResize::needs_resizewere removed.Verification already done
With
default-features = falseplus the two source fixes above,ratatui0.30.2 +ratatui-image11 builds clean and all 269 tests pass.Render was checked for real, not just compiled: both binaries were driven headlessly through a pty with the terminal capability probes answered (DA1, DSR,
CSI 16 tcell-size, kitty graphicsAPC _G), and the escape stream replayed into a 40x120 character grid. Baseline 0.29 and candidate 0.30.2 produce byte-identical grids — 550 non-blank cells and 4407 SGR-styled cells each, across the initial frame and after navigation keys. No blank-screen or layout regression.So the upgrade is viable; it just needs a human to own the packaging decision and the source edits.
Sequencing — do this after the in-flight TUI work lands
Four feature branches are currently mid-flight against
ratatui0.29, totalling roughly 1,870 changed lines undersrc/tui/:feat/tui-settings-view(13 files)feat/tui-bottom-player-bar(12 files, includingwidgets/album_art.rs)feat/tui-enhanced-speaker-list(6 files)feat/tui-drop-zone-mode(5 files)All four touch
src/tui/types.rs, which holds theStatefulProtocolfield. Landing a breaking render-API bump now would force all four to rebase across it simultaneously. Recommend letting them merge first, then doing this upgrade as one focused PR.Suggested checklist
default-features = false, or accept libchafa across all four release targets + CI + Homebrewratatuito 0.30 andratatui-imageto 11 in the same commitalbum_art.rsfixes (FontSizefields,StatefulImage::default())Rect→Sizeand clipping changesratatui-image11.1.0 — 11.0.3 as pinned in chore(deps): bump ratatui-image from 3.0.0 to 11.0.3 #72 is already four patches behind, and 12.0.0-rc.0 is out