- Remove: collections and artwork clearing are best effort in Steam's JS, and the host carries on to delete the files when Steam isn't running (Android apps and devkit titles). - Devkit titles: the shortcut is found by devkit id, the saved id, or an executable/start folder inside the title's folder; never by display name. Steam's overviews don't carry devkit_gameid (checked on the Frame 2026-09-28), so 'list' now reads exe/start dir from app details. - Photo-based grid/wide/hero slots render as JPEG (a noise-heavy 3840x1240 hero was over 12 MiB as PNG on the Frame); the logo stays transparent PNG. Rendering gets 75 s and retries once with generated art. Each slot is cleared before it is set, since Steam keeps .png and .jpg side by side. - Devkit titles keep their own VR flag (vr=None skips SetShortcutIsVR) and their Sideloaded collection. - A failed title install's cleanup can't replace the original error. - refresh_art for devkit titles (frame_titles.refresh_art). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Library fixtures
icon.png is a synthetic 2×2 RGBA fixture with opaque, half-transparent and
transparent pixels. steam-responses.json includes the Open Saber Plus
shortcut ID/name and home path read from the Frame's existing metadata on
2026-09-28; the configure response is synthetic, matching our helper's
contract. Tests never contact the network.
The existing fakeframe CEF shim models artwork and collection methods from
SteamTracking's ClientExtracted/steamui/chunk~2dcc5aaf7.js and
SteamDeckHomebrew/decky-frontend-lib's src/globals/steam-client/App.ts, read
2026-09-28. These methods were not captured from this headset: Steam's client
was unavailable. The Node-based test runs the actual generated JavaScript
against that fixture; it is skipped when Node is absent.
icon.jpg is the same synthetic icon converted with macOS sips to exercise
JPEG SOF parsing. sips is not used by the product or tests.