A custom plugin store for Decky Loader, holding my plugins for the Lenovo Legion Go family. Add the address once and they install and update through Decky's own Store tab, like anything else.
Copy this address:
https://decky.rayek.workers.dev
On the device, open Decky → Settings → General → Store channel, switch it to Custom, and paste the address into the field that appears. The Store tab then lists everything below.
Switching back to Default at any time restores the official store. Plugins already installed from here stay installed.
LeGoTDP sets AMD CPU TDP limits from the Steam overlay on the Legion Go 2 and Legion Go S. Preset ladders spaced against each machine's own firmware ceilings, per-game profiles with separate battery and charging limits, and live power draw read from RAPL.
LeGoVibeControl controls vibration intensity, pattern and touchpad haptics on the Legion Go and Legion Go 2. Five rumble patterns, a touchpad motor set apart from the handles, and per-game profiles.
LeGo2BrightnessFix makes the Steam brightness slider work on the Legion Go 2 OLED while the panel is in HDR, and gives games the panel's real HDR metadata instead of DXVK's 1499 nit placeholder. Both halves are automatic and stand down whenever they are not needed.
DeckyVibranceHDR is saturation control under gamescope, in SDR and HDR alike. Which mapping applies is read from the panel's EDID rather than the model name, so it is not tied to one handheld.
There is no server. plugins.json is the entire store: Decky fetches it, parses it as a list
of plugins, and downloads each zip straight from its own GitHub release.
build_store.py regenerates the file. It reads plugin.json from each plugin repo for the
name, author, description and tags, asks GitHub for the latest release, and hashes the
published zip so Decky can verify what it downloaded. Run it after a release and commit the
result. The address never changes.
python build_store.py
git commit -am "Refresh the store" && git pushThe file is served by GitHub Pages from main, and worker.js fronts it at the address
above. A push takes a minute or so to appear.
The worker exists for one reason. Decky adds an X-Decky-Version header, which makes the
request non-simple, so the browser sends a OPTIONS preflight first and only issues the real
GET if the answer names that header. No static host answers it: GitHub Pages replies
405, raw.githubusercontent 403, and jsDelivr replies 200 but without
Access-Control-Allow-Headers, which the browser rejects just the same. A blocked request
leaves the store spinning forever rather than showing an error, because Store.tsx has no
catch around the fetch.
The worker never needs redeploying. It reads whatever plugins.json currently says.
Three details the file has to get right, all handled by the generator:
artifactmust be present on every version. Without it Decky falls back to the official CDN, which does not have these plugins.hashis the SHA-256 of the zip and is verified after download; a mismatch refuses the install.namemust matchplugin.jsonexactly, because that is how Decky matches an installed plugin against a store entry when it checks for updates.
Plugins are BSD 3-Clause. See each repository for its own licence and notices.



