[Bug]: Lift for Business shows the silhouette - depot metadata is core_metadata_{left,right}.json
- Dominant language
- Rust
- Stars
- 21k
- Forks
- 675
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 172
Description
### Pre-flight checklist
- [x] I searched [existing issues](https://github.com/AprilNEA/OpenLogi/issues?q=is%3Aissue) and this is not a duplicate.
- [x] I am on the [latest release](https://github.com/AprilNEA/OpenLogi/releases/latest) or a recent `master` build.
- [x] I quit **Logi Options+** before running OpenLogi (the two apps fight over HID++ access and only one can own a receiver at a time).
### Which part of OpenLogi?
GUI (desktop app)
### OpenLogi version
0.8.3
### Operating system
macOS
### OS version & architecture
macOS 26.6 (25G70), Apple Silicon (arm64)
### Device model
Logitech Lift for Business, left-handed (046d:b033, ext=06)
### How is the device connected?
Bluetooth (direct, no receiver)
### Affected area(s)
- [ ] Device discovery / detection
- [ ] Button remapping
- [ ] DPI control
- [ ] SmartShift
- [ ] Per-application profiles
- [ ] Battery status
- [ ] Settings / configuration (TOML)
- [ ] Auto-update
- [ ] Menu bar / tray
- [x] Other
### What happened?
My **LIFT for Business** (left-handed SKU, `046d:b033`, `ext=06`, Bluetooth-direct) is detected and works fine — buttons, DPI, battery — but the device card and the Buttons page show the synthetic silhouette instead of the render.
The render is not missing from the catalog: `mx_vertical_mini_for_business` is in `index.json` (`modelId: 2b033`) and the sync had already downloaded `front_ext_6.png` into the cache. What the depot does *not* ship is any of `METADATA_FILES` (`core_metadata.json`, `metadata_full.json`, `metadata.json`). Because the Lift is sold in left- and right-handed SKUs, Logi splits the hotspot metadata per handedness and names it in the manifest:
```json
{ "modelId": "2b033_ext6",
"resources": [
{ "key": "device_image", "src": "front_ext_6.png" },
{ "key": "device_buttons_image", "src": "front_ext_6.png" },
{ "key": "image_metadata", "src": "core_metadata_left.json" },
{ "key": "device_easyswitch_image","src": "back_ext_6.png" }
] }
```
(`2b033`, `_ext5` and `_ext7` point at `core_metadata_right.json`.)
Two consequences:
1. `DeviceEntry::baseline_files()` (`crates/openlogi-assets/src/index.rs`) only fetches a metadata file whose name is in `METADATA_FILES`, so no metadata is ever downloaded for this depot. My cache after a normal sync held exactly `front_ext_6.png` + `manifest.json`.
2. `AssetResolver::load_files()` (`crates/openlogi-desktop/src/services/assets.rs`) starts with `let Some(&meta_name) = METADATA_FILES.iter().find(|n| dir.join(n).exists()) else { continue; };`, so the depot is skipped before the render is ever considered and the device falls through to the silhouette — even though the correct variant PNG is already in the cache.
Verified by hand: copying `core_metadata_left.json` to `core_metadata.json` (plus `back_ext_6.png`) from the Logi Options+ depot into `~/.local/share/openlogi/assets/mx_vertical_mini_for_business/` makes both the render and the button hotspots appear correctly, with no other change.
Suggested fix: resolve the metadata filename through the manifest's `image_metadata` resource for the device's variant — the same `resource_for_variant` mechanism `load_files` already uses for `device_image` / `device_buttons_image` — and fall back to `METADATA_FILES` when the manifest names none. `"image_metadata"` would also need adding to the variant loop in `services/assets/sync.rs` so the file is downloaded in the first place. That should cover every Lift SKU (`_ext5` / `_ext6` / `_ext7`) and any other depot that splits metadata per handedness.
Happy to open a PR if that approach looks right.
### Steps to reproduce
1. Pair a Logitech Lift / Lift for Business over Bluetooth (mine: `2b033`, `ext=06`, left-handed).
2. Let the asset sync run — `~/.local/share/openlogi/assets/mx_vertical_mini_for_business/` ends up with only `front_ext_6.png` and `manifest.json`.
3. Open the GUI: the device card and the Buttons page show the generic silhouette instead of the Lift render.
### Diagnostics report
```markdown
```
### `openlogi list` output
```text
(inventory read from the running agent)
LIFT B (-, vid=046d pid=b033)
└─ slot 255 ● LIFT For Business (mouse, wpid=?, battery=30% low (discharging))
model_ids=[b033,0000,0000] ext=06 serial= unit_id= transports=btle
```
### Logs
```shell
```
### macOS permissions (if applicable)
- [ ] OpenLogi has **Accessibility** permission (needed to remap buttons via the event tap).
- [ ] OpenLogi has **Input Monitoring** permission (needed for Bluetooth-direct devices and capture).
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with DeviceEntry::baseline_files() in crates/openlogi-assets/src/index.rs and AssetResolver::load_files() in crates/openlogi-desktop/src/services/assets.rs, then inspect the variant loop in services/assets/sync.rs. Trace how the manifest's image_metadata resource is resolved and downloaded for the Lift variants. Done means a normal sync retrieves the handedness-specific metadata and the GUI shows the Lift render and button hotspots instead of the silhouette.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100