mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-25 15:00:25 +01:00
* Record Steam Frame plugin research and fresh read-only evidence * Update Decky research for official store audit --------- Co-authored-by: SAPHID <saphid@users.noreply.github.com>
142 lines
10 KiB
Markdown
142 lines
10 KiB
Markdown
# Plugin and modding research
|
|
|
|
Checked **2026-10-25**. Decision: keep the experimental, reversible Decky manager
|
|
and ship Frame Control's own sandboxed panel API as the supported way to add
|
|
local features. Both implementations already landed in the replacement job
|
|
while the original job was unavailable. This report consolidates their evidence
|
|
and the original research questions; it does not claim another loader was built.
|
|
|
|
## Can Decky run on Frame?
|
|
|
|
**Its ARM64 backend and Steam shared-context injection work on the tested build.
|
|
A usable Decky menu inside VR remains unverified.** Do not equate an active
|
|
service or a JavaScript plugin registration with a working headset interface.
|
|
|
|
| Requirement | Evidence | Consequence |
|
|
| --- | --- | --- |
|
|
| ARM64 Linux binary | Upstream [3.3.0](https://github.com/SteamDeckHomebrew/decky-loader/releases/tag/v3.3.0) has `PluginLoader-arm64`; Frame reports `aarch64` | ARM is not itself a blocker. Individual plugins may still ship x86 binaries or assume Deck hardware. |
|
|
| Steam Gamepad UI and CEF | Loopback `127.0.0.1:8080/json/list` exposes `SharedJSContext` plus distinct SteamVR pages | The shared context exists; the VR shell is a separate integration target. |
|
|
| CEF enable marker | `~/.steam/steam/.cef-enable-remote-debugging` is absent, but CEF already answers | No marker or Steam launch flag change is needed on this build. |
|
|
| User service manager | `systemctl --user show-environment` succeeds | A per-user service works without installing an upstream root service. The manager is degraded by a stale failed Decky unit, although its unit file is gone. |
|
|
| Filesystem | `/` currently mounts `rw` on Btrfs, `/home` mounts `rw` | This is an observation of this device, not a stock-image guarantee. Do not disable SteamOS read-only protection or install packages in `/usr`. |
|
|
| Homebrew folder | `~/homebrew` is absent | It is an installer convention, not a preinstalled SteamOS plugin API. Frame Control uses a separate managed directory. |
|
|
| Visible menu | Earlier tests registered Decky's tab only in shared JavaScript; SteamVR had no Decky overlay; headset was in standby | QAM visibility, controller input and a real plugin's visible result remain unverified. |
|
|
|
|
The fresh [read-only probe](evidence/plugins-2026-10-25.json) records SteamOS
|
|
`0.5.6`, `VARIANT_ID=vr`, build `20261022.6153909`. It confirms CEF, architecture,
|
|
mounts, user-service availability, and absence of a running managed or upstream
|
|
Decky installation. This retry did not install anything or restart Steam.
|
|
|
|
The replacement job's initial [test record](decky-frame.md) reports:
|
|
|
|
- Decky 3.3.0 started as the normal `steamos` user and injected into
|
|
`SharedJSContext`.
|
|
- Install → status → update → status → remove → status succeeded on the Frame.
|
|
Removal left the unit, binary and port 1337 absent, while preserving user data.
|
|
- ProtonDB Badges 1.1.0 loaded as a passive plugin and appeared in Decky's
|
|
shared-context registry. Its badge or menu was not seen inside VR.
|
|
- Injected frontend code can outlive backend removal until Steam's web helper
|
|
restarts. An earlier helper-restart test cleared the globals; this retry did
|
|
not repeat it.
|
|
|
|
These are prior documented results, separate from the fresh read-only probe.
|
|
The coordinator then ran a separate, locked
|
|
[official-store compatibility audit](decky-frame.md#official-store-plugin-audit-2026-10-25)
|
|
on the same Frame OS build. Seven plugins logged backend loads. A managed
|
|
ProtonDB Badges 1.3.4 store install, update and remove also succeeded. The
|
|
headset stayed unworn, so these results still do not establish VR UI use.
|
|
|
|
## Installer and update choice
|
|
|
|
The upstream [installer at e42a3c8](https://github.com/SteamDeckHomebrew/decky-installer/blob/e42a3c828de90673959b4de26cf5c5d2c7830554/cli/install_release.sh)
|
|
escalates through sudo, creates `~/homebrew/plugins` and `services`, writes the
|
|
CEF marker and a system unit under `/etc/systemd/system`, and starts Decky as
|
|
root. Its architecture switch supports `aarch64|arm64`. Running this installer
|
|
is unnecessary for a compatibility check and grants more access than a panel
|
|
extension needs.
|
|
|
|
Frame Control's [manager](../ui/frame_decky.py) instead downloads the official
|
|
ARM64 asset, checks GitHub's published SHA-256 and the ELF machine, and writes
|
|
only under `~/.local/share/frame-control/decky` and `~/.config/systemd/user`.
|
|
It refuses an upstream system-service installation, requires active CEF before
|
|
install/update, and restores the previous binary, receipt and unit if applying
|
|
an update fails. Existing tests exercise that rollback with a failed service
|
|
start. These checks do not prove every possible OS or Steam update is safe.
|
|
|
|
The binary is downloaded on demand, not bundled. Plugin discovery lists the
|
|
managed directory and upstream `~/homebrew/plugins`. The later
|
|
[store manager](../ui/frame_decky_store.py) exposes official entries in the PC
|
|
app and opt-in headset panel. It verifies archive digests, blocks root and
|
|
non-ARM64 binaries, and changes only its own plugin folders. That is file and
|
|
backend support, not a working VR plugin page. Decky plugins can execute
|
|
backend code and are not isolated by Frame Control's HTML extension sandbox.
|
|
|
|
Home-directory state is expected to survive SteamOS image updates, based on
|
|
SteamOS's layout; **an actual OS update and reboot persistence test has not been
|
|
performed**. Steam frontend changes, CEF availability, libc requirements and
|
|
plugin hardware assumptions can still break Decky. On failure, remove the user
|
|
service using [the documented removal command](decky-frame.md#opt-in-and-remove);
|
|
its removal path does not require a working CEF target. Test the sequence again
|
|
on each supported OS build before expanding support claims.
|
|
|
|
## Other paths
|
|
|
|
| Path | What it enables | Current limits and choice |
|
|
| --- | --- | --- |
|
|
| Decky plugins | Steam frontend hooks, optional Python backends | Seven official-store plugins logged backend loads on ARM64. Store install/update/remove worked for ProtonDB Badges. VR pages and controller input remain unverified. Keep experimental. |
|
|
| [CSS Loader](https://github.com/suchmememanyskill/SDH-CssLoader) / [DeckThemes](https://docs.deckthemes.com/) | Stylesheets applied to Steam UI | CSS Loader 2.1.3 backend loaded on Frame. No theme was applied or visually tested. Deck themes do not establish compatibility with Frame's separate VR shell. |
|
|
| User home / SteamOS homebrew | User services, user Flatpaks, files and helpers | Use owned folders and explicit uninstall. A folder named `homebrew` supplies no discovery or security boundary by itself. No rootfs changes needed for the chosen path. |
|
|
| Android / Lepton | Sideloaded apps, game-specific content and per-app settings | Frame Control already manages APKs and ADB. Lepton runs Android containers, not Steam's CEF UI; an Android mod does not add a Steam dashboard tab. No new Android mod was tested here. See [APKs](apks.md), [VR APKs](vr-apks.md), and [game mods](mods.md). |
|
|
| Frame Control extensions | Third-party HTML/CSS/JS panels with a small read-only bridge | Shipped in [#194](https://github.com/saphid/frame-control/pull/194), with a manifest, local folder, sandbox, example and [author guide](extensions.md). No Python imports, arbitrary SSH commands or write actions are exposed. |
|
|
| Frame Control's headset panel | Runs the local tools and extensions as a SteamVR panel | Shipped in [#198](https://github.com/saphid/frame-control/pull/198), expanded in [#201](https://github.com/saphid/frame-control/pull/201). Page/API execution and uninstall were tested; wearer-visible pixels and controller interaction remain unverified. See [test record](headset-app.md). |
|
|
|
|
The extension iframe has `sandbox="allow-scripts"`, an opaque origin, restrictive
|
|
CSP and a `postMessage` bridge accepting only `capabilities` and a reduced
|
|
`status` snapshot from the active frame. It is useful for local dashboards and
|
|
small tools today. It cannot replace the full Decky API. Third-party code still
|
|
needs review: an iframe may navigate itself externally, and local installation
|
|
does not establish publisher trust.
|
|
|
|
Extensions are loaded only when opened and are removed by closing their panel
|
|
and deleting their own directory. They modify no SteamOS files. The
|
|
[compatibility follow-up](https://github.com/saphid/frame-control/pull/209) adds
|
|
manifest `apiVersion` validation during discovery and asset serving, with
|
|
existing manifests defaulting to version 1. It rejects incompatible panels
|
|
even when requested through a direct asset URL.
|
|
|
|
## Licences: separate download versus bundling
|
|
|
|
Decky's [licence](https://github.com/SteamDeckHomebrew/decky-loader/blob/00cd202872b85868071b041c8f1b34e734147195/LICENSE)
|
|
is GPL version 2. Frame Control is MIT-licensed. The integration contains its
|
|
own service-management code and downloads the upstream executable as a separate
|
|
program. It does not incorporate Decky source or ship its binary in Frame
|
|
Control installers. Keep the upstream licence/source links visible to users
|
|
who opt in; installing a separate GPL program does not by itself relicense
|
|
Frame Control's independent code.
|
|
|
|
If a future release bundles or mirrors Decky binaries, the distributor must
|
|
preserve copyright/licence notices and satisfy GPLv2's corresponding-source
|
|
requirements for the exact binary, including modifications and build scripts
|
|
as applicable. A link to an evolving default branch is not a substitute for
|
|
meeting those distribution obligations. Mere aggregation and deriving or
|
|
linking a combined work are different questions; reassess the boundary if
|
|
Decky code is incorporated. Each plugin, theme and bundled dependency has its
|
|
own licence and assets to check independently. The existing
|
|
[third-party notices](../THIRD_PARTY_NOTICES.md) describe software already
|
|
distributed with Frame Control.
|
|
|
|
## Next checks
|
|
|
|
1. On a worn Frame, establish an accessible Decky menu or implement an adapter
|
|
for the VR shell. Verify a plugin's visible result and controller navigation
|
|
before describing store-installed plugins as usable inside VR.
|
|
2. Verify the Frame Control panel and example extension visually, including
|
|
opening, refreshing and closing with the controllers.
|
|
3. Test a normal Steam restart, reboot and SteamOS update with a disposable
|
|
managed install; confirm removal still works with CEF unavailable. Retain
|
|
the experimental label until those checks pass.
|
|
|
|
The release coordinator owns those ongoing headset-integration checks. This
|
|
retry leaves the headset untouched and hands over the research and compatibility
|
|
follow-up instead of running concurrent loader experiments.
|