mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-26 15:02:22 +01:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4d8073e31 | ||
|
|
ff49b44350 | ||
|
|
9aa26a8322 | ||
|
|
8d9d4807c3 |
No files matched your search
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "frame-control",
|
||||
"version": "0.4.39",
|
||||
"version": "0.4.40",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "frame-control",
|
||||
"version": "0.4.39",
|
||||
"version": "0.4.40",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"electron": "^44.4.5",
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "frame-control",
|
||||
"productName": "Frame Control",
|
||||
"version": "0.4.39",
|
||||
"version": "0.4.40",
|
||||
"description": "Desktop app for managing a Valve Steam Frame over SSH",
|
||||
"private": true,
|
||||
"main": "main.js",
|
||||
|
||||
@@ -5,7 +5,7 @@ Release baseline: Frame Control **v0.4.39**, 26 October 2026. Rows also identify
|
||||
| Feature | Real Frame + physical PC tested | VM only | Untested or limited | Last check and proof |
|
||||
|---|---|---|---|---|
|
||||
| Mac desktop release — tested on a real Mac | Physical MacBook Air (MacBookAir9,1), Intel Core i3, macOS 15.7.7 (24G720): official v0.4.39 x64 DMG verified, installed and launched. Native UI, preference persistence across restart (original file restored), bundled Python logs, update check, offline OBS Start/Stop and 116-entry Decky store checked. A 40-byte relay upload/readback/delete passed under coordinator/headset locks | No | No quarantined Safari/Chrome download or Gatekeeper override test; native Open at Login/menu automation unavailable. Direct frame.local had no route and the app refused a stale SSH identity. Relay transfer is not native Mac transfer acceptance. Real OBS/Framey VR unverified. Quit exposed a server cleanup race; fix #284 has physical-Mac regression coverage, not a released fix | 26 Oct, official v0.4.39 tag `fd0b0a9`: [Intel release evidence](evidence/mac-v0439-2026-10-26.md); [earlier ARM64 failure](evidence/mac-desktop-2026-10-26.md) |
|
||||
| Core title smoke test | Linux lxso2 installed and removed reserved native/Proton titles on the real Frame; all 13 steps passed. ARM64 and Windows titles launched | No | The x86_64 title could not launch because Steam Linux Runtime 4.0 was not installed. The headset was unworn; visible rendering and controller input were not checked. Other feature paths retain their separate limits below | 26 Oct, v0.4.38 exact tag `d87b863`, Frame OS 0.5.6 build `20261022.6153909`: [latest release smoke](evidence/v0438-release-smoke-2026-10-26.md); [earlier detailed results](evidence/round2-smoke-2026-10-25.json) |
|
||||
| Core title smoke test | Linux lxso2 installed and removed reserved native/Proton titles on the real Frame; all 13 steps passed. ARM64 and Windows titles launched | No | The x86_64 title could not launch because Steam Linux Runtime 4.0 was not installed. The headset was unworn; visible rendering and controller input were not checked. Other feature paths retain their separate limits below | 26 Oct, v0.4.40 candidate source `9aa26a8`, Frame OS 0.5.6 build `20261022.6153909`: [latest 13/13 smoke](evidence/v0440-candidate-frame-2026-10-26.md); [earlier tagged smoke](evidence/v0438-release-smoke-2026-10-26.md) |
|
||||
| Windows desktop in the headset | No physical Windows PC test | Windows 11 VM sent a whole desktop to a real Frame; this used an intermediate fix, not the final native DLL | Physical GPU, capture and controller input; individual windows unavailable in bundled DXGI build | 24 Oct, v0.4.10 installer + candidate fix: [VM log](evidence/windows-vm-2026-10-24.md), [PC guide](pc-in-headset.md) |
|
||||
| Linux desktop in the headset | No | No | Native Linux PC capture is disabled; lxso2 lacked a desktop portal and PipeWire session. The separate Steam `-pipewire` helper is not Frame Control's PC capture | 24 Oct, v0.4.17: [host audit](evidence/linux-pc-host-lxso2-2026-10-24.md), [Steam helper PR #163](https://github.com/saphid/frame-control/pull/163) |
|
||||
| Mac desktop in the headset | A physical Mac sent its screen/window to a real Frame | No | Current v0.4.26 Mac installer and worn-headset controller input have not been repeated | 28 Sep, pre-v0.4 / Frame OS 0.4.1: [Mac guide and measurement](streaming.md#b-show-the-macs-desktop-inside-the-frame) |
|
||||
@@ -23,7 +23,7 @@ Release baseline: Frame Control **v0.4.39**, 26 October 2026. Rows also identify
|
||||
| Passthrough in recordings | Real room pixels in OBS and a production MP4 after safe SteamVR wake | No | **Yes** for the checked 0.5.6 mirror. Raw cameras are not opened. Other games/modes and Steam clips may differ | 25 Oct: [validation](evidence/obs-validation-2026-10-25.md), [recording guide](recording.md#does-record-include-passthrough) |
|
||||
| Open at login | No Frame needed; Linux autostart file toggled on a physical Linux host with an isolated config directory | No | A full login session and physical Windows/macOS host login have not been checked; OS API calls were unit tested | 25 Oct, v0.4.26: [PR #189](https://github.com/saphid/frame-control/pull/189) |
|
||||
| Local Frame Control extensions | Example panel displayed live Frame status in a browser preview; the real Frame served a read-only example in the experimental headset panel | No | No wearer-visible extension view; third-party extensions and physical Windows/macOS extension folders untested | 25 Oct, v0.4.29: [PR #194](https://github.com/saphid/frame-control/pull/194), [PR #201](https://github.com/saphid/frame-control/pull/201), [extension guide](extensions.md) |
|
||||
| Experimental Frame Control SteamVR panel | Frame OS 0.5.6 registered and served the opt-in overlay. A later unattended check safely woke SteamVR and found the panel in stereo compositor and mirror captures; it removed its temporary service and restored power settings | No | No person wore the headset for that check. Physical controller input, scrolling, VR keyboard, comfort and legibility remain unverified. The large status view has browser and packaging checks, not a wearer review | 26 Oct, v0.4.29–0.4.39: [panel PR #201](https://github.com/saphid/frame-control/pull/201), [unattended evidence](evidence/framey-vr-2026-10-25/README.md), [new standby-gated exercise](evidence/framey-vr-standby-gate-2026-10-26.md), [worn checklist](framey-vr-check.md) |
|
||||
| Experimental Frame Control SteamVR panel | Frame OS 0.5.6 registered and served the opt-in overlay. A later unattended check safely woke SteamVR and found the panel in stereo compositor and mirror captures; it removed its temporary service and restored power settings | No | No person wore the headset for that check. Physical controller input, scrolling, VR keyboard, comfort and legibility remain unverified. The large status view has browser and packaging checks, not a wearer review | 26 Oct, v0.4.29–0.4.39: [panel PR #201](https://github.com/saphid/frame-control/pull/201), [unattended evidence](evidence/framey-vr-2026-10-25/README.md), [latest candidate sample exercise](evidence/v0440-candidate-frame-2026-10-26.md), [earlier standby-gated exercise](evidence/framey-vr-standby-gate-2026-10-26.md), [worn checklist](framey-vr-check.md) |
|
||||
| Experimental Decky Loader manager | Frame OS 0.5.6 ARM64 user-service install/status/update/remove and managed ProtonDB install/update/remove passed earlier. A private Decky 3.3.0 service returned read-only ProtonDB and Steam Status setting RPCs; a later locked check verified the official Notebook default drawing/save/reopen flow and Simple Timer backend events in local Chromium | No | The loader remains opt-in. Installs/updates reject an archive whose Decky name collides with another installed plugin before download and under the headset transaction lock; this safety path has host/fake Frame tests, not a new real-headset collision test. Post-release main after PR #286 classifies the 116 exact-version plugins as 1 works (Notebook default flow only), 49 partial, 55 broken and 11 not applicable; v0.4.39 shipped the earlier 1/45/59/11 catalog. Deck Shelves moved to partial after its exact chunked frontend rendered settings in local Chromium; its backend and Steam Home shelves remain unverified. Steamback, PlayTime and Deck Settings became partial after detached read-only library/user snapshots and isolated amd64 backend checks; their official ARM64 backends, automatic behavior and VR panels remain unverified. A read-only Steam bridge returned the Frame country, install folders and system information; IsThereAnyDeal selected that country in local Chromium, but its deployed HTTP endpoint and deal lookup remain unverified. An isolated ARM64 LocalSend core answered its info endpoint, but the official x86-only plugin archive and file transfers remain blocked. Three official audio plugins had local real-backend controls and independent virtual-audio readbacks, but their ARM64 Frame audio sessions and physical output remain unverified. Most official backends and VR controls remain unverified. Physical controller use and wearer-visible official panels remain unverified | 26 Oct, v0.4.31–0.4.39: [managed store PR #208](https://github.com/saphid/frame-control/pull/208), [name-collision PR #269](https://github.com/saphid/frame-control/pull/269), [catalog PR #266](https://github.com/saphid/frame-control/pull/266), [backend event evidence](evidence/framey-events-backend-2026-10-26.json), [Steam read PR #274](https://github.com/saphid/frame-control/pull/274), [LocalSend evidence PR #275](https://github.com/saphid/frame-control/pull/275), [local audio evidence](evidence/framey-audio-backends-2026-10-26.md), [post-release library evidence](evidence/framey-library-context-2026-10-26.md), [compatibility table](framey-compatibility.md) |
|
||||
| Experimental Framey VR plugin panels and store | Unattended Frame OS 0.5.6 runs showed the Framey sample panel in stereo compositor and mirror captures. The latest standby-gated exercise restored the original power settings and released its shared lock. Synthetic OpenVR clicks changed a live sample setting, read its Decky backend file and confirmed it after a fresh iframe reopen | No | This was the repository sample, not an official store plugin. Physical controllers, native scrolling, VR keyboard, wearer comfort and legibility remain unverified. CSS Loader and SteamGridDB exact archives passed fake Frame install/remove and panel packing; this does not establish theme or artwork controls in VR. Panel-local backend events and React toasts have local/real-backend checks, but no wearer review. Pause Games and Tailscale Control settings render in local Chromium; their live actions are unverified. The 116-plugin catalog had 60 fake installs/removals and 56 expected blocks; post-release PR #282 recorded 101 local Chromium initializers ready and 15 failed, up from 98/18 in v0.4.39. Notebook is marked works only for its default drawing/save/reopen flow | 26 Oct, v0.4.38–0.4.39: [latest unworn sample evidence](evidence/framey-vr-standby-gate-2026-10-26.md), [backend event PR #270](https://github.com/saphid/frame-control/pull/270), [settings/cache PR #271](https://github.com/saphid/frame-control/pull/271), [post-release sample exercise](evidence/v0439-release-2026-10-26.md#post-release-framey-library-change-282), [worn checklist](framey-vr-check.md) |
|
||||
|
||||
|
||||
@@ -1,222 +0,0 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"timeUtc": "2026-10-26T03:29:05.328492+00:00",
|
||||
"baseCommit": "c89ddff",
|
||||
"scope": "Finite Framey-local DFL component/CSS registry and explicit unsupported optional UI-audio export",
|
||||
"upstreamReferences": [
|
||||
"https://github.com/SteamDeckHomebrew/decky-frontend-lib/blob/main/src/webpack.ts",
|
||||
"https://github.com/SteamDeckHomebrew/decky-frontend-lib/blob/main/src/class-mapper.ts"
|
||||
],
|
||||
"plugins": [
|
||||
{
|
||||
"id": 16,
|
||||
"name": "Audio Loader",
|
||||
"version": "1.6.1",
|
||||
"sha256": "fd5a090c2e2cd4da6723d7bd08937ab31b9f8d4663510431713da531343e303f",
|
||||
"status": "broken",
|
||||
"reason": "This plugin needs root and is not supported by the Frame user service. Steam UI sound lookup is present as explicitly unsupported; the frontend still requires Steam m_GamepadUIAudioStore.m_AudioPlaybackManager, which is unavailable in the isolated panel.",
|
||||
"browser": {
|
||||
"id": 16,
|
||||
"name": "Audio Loader",
|
||||
"ready": false,
|
||||
"error": "Cannot read properties of undefined (reading 'm_AudioPlaybackManager')",
|
||||
"logs": [
|
||||
{
|
||||
"kind": "warn",
|
||||
"message": "Resolve failed: [object Object] promise [object Promise]"
|
||||
}
|
||||
],
|
||||
"methods": [
|
||||
"store_read"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 36,
|
||||
"name": "SteamGridDB",
|
||||
"version": "1.8.1",
|
||||
"sha256": "e84f5b1f111af8862b06218479491fbf61036e1bfd9f16f93f9901e9b9ebc5e0",
|
||||
"status": "broken",
|
||||
"reason": "Local module mapping is available; frontend still requires the Steam LibraryContextMenu implementation, which has no target in the isolated Framey panel.",
|
||||
"browser": {
|
||||
"id": 36,
|
||||
"name": "SteamGridDB",
|
||||
"ready": false,
|
||||
"error": "Cannot convert undefined or null to object",
|
||||
"logs": [],
|
||||
"methods": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 61,
|
||||
"name": "TabMaster",
|
||||
"version": "2.15.1",
|
||||
"sha256": "e08333859a32b0c177b8e9a7959c5eeeafe38f946578f7f1d161c721f0e05da5",
|
||||
"status": "partial",
|
||||
"reason": "Local Chromium rendered the QAM and navigable Overview/Filters documentation with an actual Decky 3.3.0 amd64 backend. Library-tab editing remains unavailable: Steam login/library patches and MobX reactions have no target. ARM64 and worn VR unverified.",
|
||||
"browser": {
|
||||
"id": 61,
|
||||
"name": "TabMaster",
|
||||
"ready": true,
|
||||
"error": null,
|
||||
"logs": [
|
||||
{
|
||||
"kind": "error",
|
||||
"message": "%c TabMaster %c ERROR %c background: #ff6d05; color: black; background: #c70808; color: black; background: transparent; Could not find mobx.reaction"
|
||||
}
|
||||
],
|
||||
"methods": [
|
||||
"log_message"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 84,
|
||||
"name": "Junk-Store",
|
||||
"version": "1.1.13",
|
||||
"sha256": "f7ad2a0103c85bf308929b2e96ec9aeeb0d76bcc6ae97eb1e4b5f31ffba0cbb1",
|
||||
"status": "broken",
|
||||
"reason": "Local CSS lookup fixes the loading view crash. Actual Decky 3.3.0 amd64 startup/static InitActions return a script execution/JSON error; the published scripts are not executable after extraction. Store install/login/game launch and ARM64 remain unverified.",
|
||||
"browser": {
|
||||
"id": 84,
|
||||
"name": "Junk-Store",
|
||||
"ready": true,
|
||||
"error": null,
|
||||
"logs": [],
|
||||
"methods": [
|
||||
"fetch_rss_feed",
|
||||
"execute_action"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 102,
|
||||
"name": "DeckSP",
|
||||
"version": "1.1.3",
|
||||
"sha256": "d6cbedcd64430e1f94a2b12caf936ba270f1ceafe77c6252808ff39c88640b40",
|
||||
"status": "broken",
|
||||
"reason": "Optional UI-audio lookup succeeds, but the published frontend raises \"Cannot access PluginManager before initialization\" when Steam MobX reaction lookup is unavailable. JamesDSP installation/audio routing and ARM64 remain unverified.",
|
||||
"browser": {
|
||||
"id": 102,
|
||||
"name": "DeckSP",
|
||||
"ready": false,
|
||||
"error": "Cannot access 'PluginManager' before initialization",
|
||||
"logs": [],
|
||||
"methods": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"fullCatalogFrontend": {
|
||||
"attempted": 116,
|
||||
"ready": 102,
|
||||
"failed": 14,
|
||||
"previousReady": 101,
|
||||
"newlyReady": [
|
||||
61
|
||||
],
|
||||
"regressions": [],
|
||||
"backendAndNetworkDenied": true,
|
||||
"library": "Private detached real Frame snapshot replay, not live Steam or backend verification"
|
||||
},
|
||||
"focusedBrowser": {
|
||||
"host": "Actual ui/headset.html, React 18.3.1, opaque allow-scripts iframe, exact official bundles",
|
||||
"installedPluginAndStatusResponses": "Fixture-shaped; no headset HTTP endpoint exercised",
|
||||
"backend": "Actual official Decky 3.3.0 amd64 in unprivileged network-none container; no host audio/device/data mounts",
|
||||
"deckySha256": "e80d03e641d1766a33a817cb27ab8d2e0a4633685e5d27e4de948a6687526181",
|
||||
"allowedMethods": {
|
||||
"TabMaster": [
|
||||
"log_message",
|
||||
"get_setting",
|
||||
"get_users_dict",
|
||||
"get_tags"
|
||||
],
|
||||
"Junk-Store": [
|
||||
"execute_action only init/InitActions"
|
||||
]
|
||||
},
|
||||
"checks": [
|
||||
"TabMaster QAM renders; library editing controls remain disabled",
|
||||
"TabMaster Open Docs -> Overview renders",
|
||||
"TabMaster Filters tab renders",
|
||||
"Back to plugin returns to QAM",
|
||||
"Junk-Store static InitActions via real backend returns Type Error; not promoted"
|
||||
],
|
||||
"denied": [
|
||||
"External RSS/network",
|
||||
"Other execute_action arguments",
|
||||
"Login, installation, game launch, library patching, audio playback"
|
||||
],
|
||||
"directBackendReads": {
|
||||
"TabMaster.get_setting": "default string returned",
|
||||
"TabMaster.get_users_dict": {},
|
||||
"TabMaster.get_tags": [],
|
||||
"Junk-Store.scriptMode": "0644, Python shebang present"
|
||||
}
|
||||
},
|
||||
"headset": {
|
||||
"newPluginDeviceExecution": false,
|
||||
"lockProbe": "Normal atomic lock acquired/released for read-only dependency availability probe; no service or power changes",
|
||||
"ARM64OfficialBackend": "Not exercised in this theme",
|
||||
"wornVR": false
|
||||
},
|
||||
"verification": {
|
||||
"frameyTests": 42,
|
||||
"fullServerTests": {
|
||||
"count": 1620,
|
||||
"skipped": 16,
|
||||
"result": "OK"
|
||||
},
|
||||
"siteTestFilesPassed": 2,
|
||||
"fakeFrame": {
|
||||
"attempted": 116,
|
||||
"installedRemoved": 60,
|
||||
"expectedBlockers": 56,
|
||||
"backendExecuted": false,
|
||||
"privateProject": "framey-catalog-6456d3d939",
|
||||
"projectRemoved": true,
|
||||
"baseCommit": "c89ddff"
|
||||
}
|
||||
},
|
||||
"storeRefresh": {
|
||||
"timeUtc": "2026-10-26T03:29:46.606326+00:00",
|
||||
"currentCount": 116,
|
||||
"pinnedCount": 116,
|
||||
"unchanged": true,
|
||||
"changedIds": []
|
||||
},
|
||||
"postMainMerge": {
|
||||
"mainCommit": "38c388f",
|
||||
"mergedPRs": [
|
||||
286,
|
||||
287,
|
||||
288
|
||||
],
|
||||
"frameyTests": 43,
|
||||
"fullCatalogFrontend": {
|
||||
"attempted": 116,
|
||||
"ready": 103,
|
||||
"failed": 13,
|
||||
"additionalReadyFromUpstream": [
|
||||
135
|
||||
],
|
||||
"regressionsComparedWithPreMergeAudit": []
|
||||
},
|
||||
"catalog": {
|
||||
"works": 1,
|
||||
"partial": 50,
|
||||
"broken": 54,
|
||||
"na": 11
|
||||
},
|
||||
"fullServerTests": {
|
||||
"count": 1621,
|
||||
"skipped": 16,
|
||||
"result": "OK"
|
||||
}
|
||||
},
|
||||
"cleanup": {
|
||||
"focusedBackendContainerAbsent": true,
|
||||
"loopback18770Closed": true,
|
||||
"loopback18771Closed": true,
|
||||
"fakeProjectAndVolumesRemoved": true
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
# Framey-local module lookup: official plugin checks
|
||||
|
||||
TabMaster 2.15.1 now renders its QAM and bundled documentation in local Chromium.
|
||||
Opening its docs, selecting Overview and Filters, and returning to the panel
|
||||
passed. Its status moves from **broken to partial**: library editing controls
|
||||
remain disabled because Steam login, live MobX reactions and library-page
|
||||
patches are unavailable. This is not working library-tab customization.
|
||||
|
||||
The [observations](framey-module-lookup-2026-10-26.json) pin each tested official
|
||||
archive and the actual Decky 3.3.0 amd64 binary. The complete current official
|
||||
store was refreshed: all 116 IDs, versions and digests match the catalog.
|
||||
|
||||
| Plugin | Result | Remaining limitation |
|
||||
| --- | --- | --- |
|
||||
| TabMaster 61 | Partial: QAM and documentation navigation render | Steam library editing unavailable; ARM64 and worn VR unverified |
|
||||
| Junk-Store 84 | Loading and backend-error views render without the CSS lookup crash | Actual startup/static InitActions return an execution/JSON error; extracted scripts lack executable permission; remains broken |
|
||||
| SteamGridDB 36 | Module mapping is callable | Still needs Steam's LibraryContextMenu implementation; remains broken |
|
||||
| DeckSP 102 | Optional UI-audio lookup succeeds | Published bundle accesses PluginManager before initialization when MobX reaction is absent; remains broken |
|
||||
| Audio Loader 16 | Optional UI-audio lookup succeeds | Still requires Steam's mutable audio playback store; remains broken |
|
||||
|
||||
## What ran
|
||||
|
||||
The host exposes a finite registry of its own components and styled CSS maps,
|
||||
with DFL module/export/class lookup and mapping semantics. Unknown matches return
|
||||
undefined or an empty mapping. An optional audio export explicitly reports
|
||||
unavailable; invoking playback throws. No Steam webpack cache, function-source
|
||||
signature, audio store or library patch was manufactured.
|
||||
|
||||
The full exact-bundle browser pass ran with backend and network calls denied.
|
||||
It completed 102 initializers and failed 14, versus 101/15 before this theme.
|
||||
Initializer readiness alone does not establish rendered or useful behavior.
|
||||
After integrating main’s #286/#287/#288, all 116 were retried: 103 initializers
|
||||
completed and 13 failed. The additional completion is Deck Shelves from #286;
|
||||
no previously completed initializer regressed.
|
||||
|
||||
Focused checks used actual `ui/headset.html`, React 18.3.1 and opaque
|
||||
`allow-scripts` iframes. Status/installed-plugin responses were fixture-shaped,
|
||||
and the private detached library snapshot from the earlier Frame SSH check was
|
||||
replayed. The relay allowed only TabMaster log/settings reads and Junk-Store's
|
||||
static `init/InitActions` action. TabMaster's official backend returned the
|
||||
default setting, empty users dictionary and empty tags. Junk-Store returned a
|
||||
structured Type Error, which its panel displayed. RSS/network, login, installs,
|
||||
launch actions and other backend methods were denied.
|
||||
|
||||
The unmodified Python backends ran in actual Decky 3.3.0 inside a disposable
|
||||
unprivileged amd64 container with no network, host audio, devices or user-data
|
||||
mounts. This bypasses Steam CEF and is not a headset HTTP/RPC check. The normal
|
||||
headset lock was briefly acquired and released for read-only dependency/service
|
||||
availability; no official plugin ran there in this theme. No ARM64 or worn-VR
|
||||
result is claimed.
|
||||
|
||||
## Regression checks
|
||||
|
||||
- 1,621 server tests passed, 16 skipped; all 43 focused Framey tests passed
|
||||
after integrating the latest main.
|
||||
- Both site test files passed.
|
||||
- All 116 exact archives passed the fake-Frame audit: 60 install/remove flows
|
||||
and 56 expected blockers. Official backend execution remained stubbed.
|
||||
- The unique fake-Frame project and its volumes were removed. The focused
|
||||
backend container and both loopback helpers were removed after the checks.
|
||||
|
||||
The catalog and generated compatibility table use the same status/reasons as
|
||||
both store views. The result is **1 works / 50 partial / 54 broken / 11 N/A** (including main’s independent Deck Shelves improvement);
|
||||
the majority goal remains open.
|
||||
@@ -0,0 +1,9 @@
|
||||
# v0.4.40 candidate: locked real Frame gates, 26 October 2026
|
||||
|
||||
Source commit `9aa26a8322f74144c13528b6fb41edc451ec7eea` contains merged PRs #286–#288 and the candidate 0.4.40 version bump. The Frame ran SteamOS 0.5.6 build `20261022.6153909`. These are source checks before tagged installers exist.
|
||||
|
||||
The unworn `scripts/framey-vr-check.py --exercise` acquired its random-owner `/tmp/frame-test.lock` from lxso2. Its locked read-only preflight found SteamVR activity 3 (standby), proximity 6.25, battery 100%, and original power values `false` and `5`. The repository sample panel became visible, the stereo compositor image changed, and `/dev/video99` supplied a mirror frame. Synthetic OpenVR pointer input produced a trusted click, changed the sample's live Decky setting, and the saved value survived a fresh iframe reopen. The quick action and native slider/text control paths completed; native scrolling did not move. The run exited 0, removed its temporary Decky/panel services and recovery timer, restored and read back the original power values, reported no cleanup errors, found battery 99%, and released its own lock. Private room and UI captures remain outside the repository.
|
||||
|
||||
After the Frame returned to standby, `scripts/frame-smoke.sh` acquired a separate random-owner lock. Its preflight found activity 3, proximity 6.25, and battery 100%. All **13/13** steps passed, including ARM64, x86-64 and Windows-executable install/launch/remove and final cleanup. The command exited 0, which includes successful release of its owned lock. Its private detailed result remains outside the repository.
|
||||
|
||||
These checks exercise Frame Control's repository sample and generic title paths. They do not run the official Deck Shelves backend or prove its panel or Steam Home shelves in VR. The run did not include a wearer, physical controller, VR keyboard, native scrolling, or optical comfort check. A mirror capture and changed compositor pixels do not by themselves prove wearer-visible passthrough for this run. The [compatibility table](../framey-compatibility.md) retains those limits.
|
||||
@@ -4,7 +4,7 @@ Snapshot: 2026-10-25T23:19:48.854504+00:00; 116 current visible official plugins
|
||||
|
||||
This table and both store views use [`ui/framey-compatibility.json`](../ui/framey-compatibility.json). Results apply only to the exact store ID, version and SHA-256. A changed digest/version is **unverified**. Regenerate this document with `python3 scripts/framey-compatibility-doc.py`; use `--check` in review.
|
||||
|
||||
**Works: 1 · Partial: 50 · Broken: 54 · N/A: 11.**
|
||||
**Works: 1 · Partial: 49 · Broken: 55 · N/A: 11.**
|
||||
|
||||
- **Works** requires verified useful plugin behavior with its real backend. Read the reason for the verified scope and remaining limits; it does not imply worn-VR verification.
|
||||
- **Partial** means only a subset or a local fixture scope was verified, often just frontend/settings initialization. The remaining backend/device functionality is unverified; read the reason for the exact scope.
|
||||
@@ -27,7 +27,7 @@ Open the browser audit URL in local Chromium, run `runAudit()` and inspect/downl
|
||||
|
||||
The current published digests are pinned in the JSON; if the store changed, retain/download those exact archives for reproduction. Audit downloads permit larger ZIPs for inspection; production installer limits remain 50 MiB ZIP / 150 MiB unpacked / 30 MiB per member.
|
||||
|
||||
After the VR job released the shared lock, this audit acquired it and used a private temporary Decky 3.3.0 ARM64 user service. Read-only ProtonDB `get_setting` and Steam Status `get_settings` calls succeeded through the live Steam CEF websocket. The service and private base were removed and the lock released; normal managed services stayed inactive, battery was 100 → 99, and no power setting was changed. [Redacted results](evidence/framey-official-backend-2026-10-25.json) record exactly what ran. A [2026-10-26 follow-up](evidence/framey-events-backend-2026-10-26.json) verified default Notebook drawing/save/reopen across a real backend restart and Simple Timer start/cancel, countdown/completion events, a visible toast and persisted recents/subtle mode. Only private test settings were written. Simple Timer remains partial because its own expired-timer startup raises a missing `timer_task` error; sound/suspend are unsupported. A [local audio follow-up](evidence/framey-audio-backends-2026-10-26.md) exercised Volume Mixer, Volume Boost and Mixer through real Decky 3.3.0 amd64 backends on private silent virtual audio targets. Sliders, numeric volume entry, independent server readbacks and Mixer filter persistence across a runtime restart passed. These three stay partial: real ARM64 Frame audio dependencies/session mapping remain unverified because the shared headset lock was occupied. A [library context follow-up](evidence/framey-library-context-2026-10-26.md) read 1,106 app overviews, 895 game IDs and the current public Steam ID from real Frame CEF under the shared lock. Local Chromium replayed this detached snapshot to render Deck Settings game selection, Steamback's empty save panel and PlayTime statistics/settings. Steamback and PlayTime used actual Decky 3.3.0 amd64 backends in an isolated container; their ARM64 backends and automatic game hooks remain unverified. Shotty's frontend now starts, but its published backend fails on missing `click`; it stays broken. A [chunked frontend follow-up](evidence/framey-deck-shelves-browser-2026-10-26.md) loaded Deck Shelves 2.0.0 through a managed JavaScript module route and rendered its settings in an opaque local Chromium panel. Its backend was denied; Steam Home shelves and worn VR remain unverified. A [local module lookup follow-up](evidence/framey-module-lookup-2026-10-26.md) supplies a finite registry of Framey-local controls and CSS. TabMaster QAM/docs now render; Steam library-tab editing remains unavailable. Junk-Store loading/error views render, but its real backend cannot execute the extracted startup script, so it stays broken. SteamGridDB still requires Steam context-menu internals and DeckSP still fails its published MobX fallback. TabMaster/Junk-Store ran in actual isolated amd64 Decky; no ARM64 or worn-VR result is claimed. Beyond the documented checks, official backends remain unexecuted. The separate VR job proves Frame Control/sample compositor rendering, not any official plugin. No worn-VR official-plugin result is claimed. A [local UI follow-up](evidence/framey-ui-fallbacks-2026-10-26.json) rendered Pause Games and Tailscale Control settings with all backend/network actions denied; it does not verify process pausing or Tailscale changes. A [read-only Steam bridge follow-up](evidence/framey-steam-reads-2026-10-26.json) verified actual Frame country, install folders and system information, plus IsThereAnyDeal's country dropdown in local Chromium. The installed-plugin status was fixture-shaped in that relay; plugin backends stayed denied and the deployed headset HTTP endpoint remains unverified. Earlier focused checks cover [ProtonDB](evidence/framey-browser-2026-10-25.md), [Steam Status/cache](evidence/framey-cache-browser-2026-10-25.md), [Storage Cleaner](evidence/framey-api-v1-browser-2026-10-25.md), and [legacy MusicControl](evidence/framey-legacy-2026-10-25.md).
|
||||
After the VR job released the shared lock, this audit acquired it and used a private temporary Decky 3.3.0 ARM64 user service. Read-only ProtonDB `get_setting` and Steam Status `get_settings` calls succeeded through the live Steam CEF websocket. The service and private base were removed and the lock released; normal managed services stayed inactive, battery was 100 → 99, and no power setting was changed. [Redacted results](evidence/framey-official-backend-2026-10-25.json) record exactly what ran. A [2026-10-26 follow-up](evidence/framey-events-backend-2026-10-26.json) verified default Notebook drawing/save/reopen across a real backend restart and Simple Timer start/cancel, countdown/completion events, a visible toast and persisted recents/subtle mode. Only private test settings were written. Simple Timer remains partial because its own expired-timer startup raises a missing `timer_task` error; sound/suspend are unsupported. A [local audio follow-up](evidence/framey-audio-backends-2026-10-26.md) exercised Volume Mixer, Volume Boost and Mixer through real Decky 3.3.0 amd64 backends on private silent virtual audio targets. Sliders, numeric volume entry, independent server readbacks and Mixer filter persistence across a runtime restart passed. These three stay partial: real ARM64 Frame audio dependencies/session mapping remain unverified because the shared headset lock was occupied. A [library context follow-up](evidence/framey-library-context-2026-10-26.md) read 1,106 app overviews, 895 game IDs and the current public Steam ID from real Frame CEF under the shared lock. Local Chromium replayed this detached snapshot to render Deck Settings game selection, Steamback's empty save panel and PlayTime statistics/settings. Steamback and PlayTime used actual Decky 3.3.0 amd64 backends in an isolated container; their ARM64 backends and automatic game hooks remain unverified. Shotty's frontend now starts, but its published backend fails on missing `click`; it stays broken. A [chunked frontend follow-up](evidence/framey-deck-shelves-browser-2026-10-26.md) loaded Deck Shelves 2.0.0 through a managed JavaScript module route and rendered its settings in an opaque local Chromium panel. Its backend was denied; Steam Home shelves and worn VR remain unverified. Other official backends remain unexecuted. The separate VR job proves Frame Control/sample compositor rendering, not any official plugin. No worn-VR official-plugin result is claimed. A [local UI follow-up](evidence/framey-ui-fallbacks-2026-10-26.json) rendered Pause Games and Tailscale Control settings with all backend/network actions denied; it does not verify process pausing or Tailscale changes. A [read-only Steam bridge follow-up](evidence/framey-steam-reads-2026-10-26.json) verified actual Frame country, install folders and system information, plus IsThereAnyDeal's country dropdown in local Chromium. The installed-plugin status was fixture-shaped in that relay; plugin backends stayed denied and the deployed headset HTTP endpoint remains unverified. Earlier focused checks cover [ProtonDB](evidence/framey-browser-2026-10-25.md), [Steam Status/cache](evidence/framey-cache-browser-2026-10-25.md), [Storage Cleaner](evidence/framey-api-v1-browser-2026-10-25.md), and [legacy MusicControl](evidence/framey-legacy-2026-10-25.md).
|
||||
|
||||
## Every current plugin
|
||||
|
||||
@@ -42,7 +42,7 @@ The API column shows manifest / actual bundled frontend API. Many manifests say
|
||||
| 12: MusicControl 1.1.6 | legacy / legacy | partial | Legacy media controls initialize; player discovery and playback are unverified. | static archive, local browser, fake-Frame |
|
||||
| 13: Pause Games 1.0.3 | 1 / 2 | partial | Settings render locally with inert system-key subscriptions and empty detached Steam context. Live-game discovery, process pause/resume and suspend integration are unsupported/unverified; no backend actions ran. | static archive, local browser, fake-Frame |
|
||||
| 14: ProtonDB Badges 1.3.4 | 2 / 2 | partial | Settings render locally and read-only get_setting RPC returned the default through real Decky 3.3.0 on ARM64 Frame. Steam game-page badges have no patch target; live writes and VR controls unverified. | static archive, local browser, fake-Frame, real Frame SSH |
|
||||
| 16: Audio Loader 1.6.1 | legacy / legacy | broken | This plugin needs root and is not supported by the Frame user service. Steam UI sound lookup is present as explicitly unsupported; the frontend still requires Steam m_GamepadUIAudioStore.m_AudioPlaybackManager, which is unavailable in the isolated panel. | static archive, local browser, fake-Frame |
|
||||
| 16: Audio Loader 1.6.1 | legacy / legacy | broken | This plugin needs root and is not supported by the Frame user service. Frontend audit failed: Cannot read properties of null (reading 'm_GamepadUIAudioStore'). | static archive, local browser, fake-Frame |
|
||||
| 18: Bluetooth 3.1.1 | 1 / 2 | partial | Controls render with fixture replies; actual Bluetooth discovery, labels and connections remain unverified. | static archive, local browser, fake-Frame |
|
||||
| 19: Notebook 0.1.5 | legacy / legacy | works | Default notebook drawing, save and reopen verified in Chromium with real Decky 3.3.0 ARM64, including backend restart. Per-game auto-selection and background artwork unavailable; worn-VR input unverified. | static archive, local browser, fake-Frame, real Frame SSH |
|
||||
| 21: PowerTools 2.0.3 | legacy / legacy | N/A | Not supported on Frame: Targets AMD Ryzen power controls; Frame uses an ARM64 SoC. | static archive, local browser, fake-Frame |
|
||||
@@ -55,7 +55,7 @@ The API column shows manifest / actual bundled frontend API. Many manifests say
|
||||
| 30: TunnelDeck 1.0.4 | legacy / legacy | broken | This plugin needs root and is not supported by the Frame user service. | static archive, local browser, fake-Frame |
|
||||
| 32: AutoFlatpaks 1.6.8 | legacy / legacy | broken | This plugin needs root and is not supported by the Frame user service. | static archive, local browser, fake-Frame |
|
||||
| 35: MoonDeck 1.13.0 | 1 / 2 | broken | Plugin contains a non-ARM64 Linux binary: moondeck/python/externals/yarl/_quoting_c.cpython-313-x86_64-linux-gnu.so. Frontend initializes; native CPython wheels and executables in the published archive are x86_64. | static archive, local browser, fake-Frame |
|
||||
| 36: SteamGridDB 1.8.1 | 1 / 2 | broken | Local module mapping is available; frontend still requires the Steam LibraryContextMenu implementation, which has no target in the isolated Framey panel. | static archive, local browser, fake-Frame |
|
||||
| 36: SteamGridDB 1.8.1 | 1 / 2 | broken | Frontend audit failed: DFL.createModuleMapping is not a function. | static archive, local browser, fake-Frame |
|
||||
| 37: Discord Status 1.5.0 | 1 / 2 | broken | Detached app overviews are now available, but RunningApps/lifetime observations and Steam artwork helpers still lack a live mapping. Discord activity integration remains unavailable/unverified. | static archive, local browser, fake-Frame, real Frame SSH |
|
||||
| 38: Volume Mixer 1.2.1-1 | legacy / legacy | partial | Local Chromium discovers and changes a private silent stream through the actual Decky 3.3.0 Linux backend, with independent Pulse readback. Frame ARM64 libraries/audio session and Bluetooth playback controls remain unverified. | static archive, local browser, fake-Frame, isolated Linux backend |
|
||||
| 40: Controller Tools 2.0.2 | 1 / 2 | broken | Plugin contains a non-ARM64 Linux binary: ControllerTools/bin/backend. Frontend audit failed: Audit blocks WebSocket. | static archive, local browser, fake-Frame |
|
||||
@@ -71,7 +71,7 @@ The API column shows manifest / actual bundled frontend API. Many manifests say
|
||||
| 58: Volume Boost 0.0.7 | legacy / legacy | partial | Local Chromium sync/separate sliders, numeric volume entry and cache reopen pass through the actual Decky 3.3.0 backend on a private virtual stereo sink. Frame pactl/default sink, boost above 100% and physical audio remain unverified. | static archive, local browser, fake-Frame, isolated Linux backend |
|
||||
| 59: Web Browser 1.4.3 | legacy / legacy | broken | Frontend audit failed: deckyFrontendLib.getReactRoot is not a function. | static archive, local browser, fake-Frame |
|
||||
| 60: DeckyFileServer 1.2.0 | 1 / 2 | broken | Plugin contains a non-ARM64 Linux binary: DeckyFileServer/bin/backend. | static archive, local browser, fake-Frame |
|
||||
| 61: TabMaster 2.15.1 | 1 / 2 | partial | Local Chromium rendered the QAM and navigable Overview/Filters documentation with an actual Decky 3.3.0 amd64 backend. Library-tab editing remains unavailable: Steam login/library patches and MobX reactions have no target. ARM64 and worn VR unverified. | static archive, local browser, fake-Frame |
|
||||
| 61: TabMaster 2.15.1 | 1 / 2 | broken | Frontend audit failed: Cannot read properties of null (reading 'GamepadUIAudio'). | static archive, local browser, fake-Frame |
|
||||
| 62: TS3 QuickAccess 1.2.0 | legacy / legacy | broken | Plugin contains a non-ARM64 Linux binary: ts3-qs4sd/bin/ts3-qs4sd.so. | static archive, local browser, fake-Frame |
|
||||
| 63: Free Loader 1.6.0 | 1 / 2 | broken | Unsafe plugin archive member. | static archive, local browser, fake-Frame |
|
||||
| 64: Syncthing 0.2.7 | legacy / legacy | broken | Plugin contains a non-ARM64 Linux binary: decky-syncthing/bin/decky-syncthing-watchdog. | static archive, local browser, fake-Frame |
|
||||
@@ -91,7 +91,7 @@ The API column shows manifest / actual bundled frontend API. Many manifests say
|
||||
| 80: MagicBlack 2.0.2 | 1 / 2 | N/A | Not supported on Frame: Targets a global Steam Deck screen-black overlay; the isolated panel cannot black out the Frame compositor. | static archive, local browser, fake-Frame |
|
||||
| 81: IsThereAnyDeal for Deck 1.1.1 | legacy / legacy | partial | Country settings render and select the real Frame Steam country through the read-only bridge. Settings writes, deal lookups and Steam page integration remain unverified; plugin backend calls were denied. | static archive, local browser, fake-Frame, real Frame SSH |
|
||||
| 82: MagicPods 2.0.21 | 1 / 2 | broken | Plugin contains a non-ARM64 Linux binary: MagicPodsDecky/bin/magicpodscore. Frontend audit failed: Audit blocks WebSocket. | static archive, local browser, fake-Frame |
|
||||
| 84: Junk-Store 1.1.13 | legacy / legacy | broken | Local CSS lookup fixes the loading view crash. Actual Decky 3.3.0 amd64 startup/static InitActions return a script execution/JSON error; the published scripts are not executable after extraction. Store install/login/game launch and ARM64 remain unverified. | static archive, local browser, fake-Frame |
|
||||
| 84: Junk-Store 1.1.13 | legacy / legacy | broken | Route registration succeeds; rendering fails on a missing Steam ContainerBackground component. | static archive, local browser, fake-Frame |
|
||||
| 85: Decky-Undervolt 1.0.8 | 1 / 2 | N/A | Not supported on Frame: RyzenAdj Curve Optimizer requires an AMD CPU; Frame is ARM64. | static archive, local browser, fake-Frame |
|
||||
| 87: ScreenSaver 1.1.2 | legacy / legacy | partial | Initializer succeeds; global screen overlay and idle/suspend integration have no verified VR target. | static archive, local browser, fake-Frame |
|
||||
| 88: steamdeck-input-disabler 1.0.2 | legacy / legacy | N/A | Not supported on Frame: Targets the built-in Steam Deck USB gamepad; Frame has different controllers. | static archive, local browser, fake-Frame |
|
||||
@@ -108,7 +108,7 @@ The API column shows manifest / actual bundled frontend API. Many manifests say
|
||||
| 99: Decky Zerotier 0.3.1 | 1 / 2 | broken | This plugin needs root and is not supported by the Frame user service. | static archive, local browser, fake-Frame |
|
||||
| 100: Virtual Surround Sound 0.0.5 | 1 / 2 | partial | Initializer succeeds; avatar proxy is unavailable and live audio-routing backend unverified. | static archive, local browser, fake-Frame |
|
||||
| 101: XIVOmega 1.0.2 | 1 / 2 | broken | This plugin needs root and is not supported by the Frame user service. | static archive, local browser, fake-Frame |
|
||||
| 102: DeckSP 1.1.3 | 1 / 2 | broken | Optional UI-audio lookup succeeds, but the published frontend raises "Cannot access PluginManager before initialization" when Steam MobX reaction lookup is unavailable. JamesDSP installation/audio routing and ARM64 remain unverified. | static archive, local browser, fake-Frame |
|
||||
| 102: DeckSP 1.1.3 | 1 / 2 | broken | Frontend audit failed: Cannot read properties of null (reading 'GamepadUIAudio'). | static archive, local browser, fake-Frame |
|
||||
| 103: Decky Ludusavi 1.2.2 | 1 / 2 | partial | Initializer succeeds; Flatpak Ludusavi discovery and backup/restore unverified. | static archive, local browser, fake-Frame |
|
||||
| 104: Game Sync 1.0.4 | 1 / 2 | partial | Backend get_config is intentionally rejected by the audit before initialization completes; actual backend compatibility is unknown. | static archive, local browser, fake-Frame |
|
||||
| 105: WiFi Locker 1.0.2 | 1 / 2 | broken | This plugin needs root and is not supported by the Frame user service. | static archive, local browser, fake-Frame |
|
||||
|
||||
@@ -70,15 +70,6 @@ countdown, completion toast and persisted recents/subtle mode worked. Simple
|
||||
Timer remains partial: its own expired-timer startup raises a missing
|
||||
`timer_task` error, sound/suspend are unsupported, and worn VR was not checked.
|
||||
|
||||
DFL module and class lookup searches a finite registry of Framey's own controls,
|
||||
CSS maps and an explicitly unsupported optional UI-audio player. It follows DFL's
|
||||
module/export filter and mapping contracts; unknown Steam modules return
|
||||
`undefined`, and unknown module mappings are empty. Returned IDs describe local
|
||||
Framey exports, not Steam webpack IDs. Sound playback throws an unsupported
|
||||
error, and Steam audio stores, function-source signatures and global patches are
|
||||
not fabricated. The [module lookup checks](evidence/framey-module-lookup-2026-10-26.md)
|
||||
record the resulting TabMaster documentation support and remaining blockers.
|
||||
|
||||
The host currently supplies sections, rows, buttons, toggles, text fields,
|
||||
sliders, grouped dropdowns,
|
||||
scroll containers, a modal, locale information, local panel routes and toasts,
|
||||
|
||||
@@ -63,7 +63,7 @@ def render(data):
|
||||
'A [chunked frontend follow-up](evidence/framey-deck-shelves-browser-2026-10-26.md) loaded Deck Shelves 2.0.0 '
|
||||
'through a managed JavaScript module route and rendered its settings in an opaque local Chromium panel. '
|
||||
'Its backend was denied; Steam Home shelves and worn VR remain unverified. '
|
||||
'A [local module lookup follow-up](evidence/framey-module-lookup-2026-10-26.md) supplies a finite registry of Framey-local controls and CSS. TabMaster QAM/docs now render; Steam library-tab editing remains unavailable. Junk-Store loading/error views render, but its real backend cannot execute the extracted startup script, so it stays broken. SteamGridDB still requires Steam context-menu internals and DeckSP still fails its published MobX fallback. TabMaster/Junk-Store ran in actual isolated amd64 Decky; no ARM64 or worn-VR result is claimed. Beyond the documented checks, official backends remain unexecuted. '
|
||||
'Other official backends remain unexecuted. '
|
||||
'The separate VR job proves Frame Control/sample compositor rendering, not any official plugin. '
|
||||
'No worn-VR official-plugin result is claimed. '
|
||||
'A [local UI follow-up](evidence/framey-ui-fallbacks-2026-10-26.json) rendered Pause Games and Tailscale Control settings '
|
||||
|
||||
@@ -170,35 +170,7 @@ const undo=api.routerHook.addRoute('/plugin/details',LocalRoute);
|
||||
assert.equal(window.DFL.Navigation.Navigate('/plugin/details'),true);
|
||||
assert.equal(nodes(window.__surface({plugin}),LocalRoute).length,1);
|
||||
assert.equal(window.DFL.Navigation.Navigate('/decky/store'),false);
|
||||
// Bounded lookup uses DFL's module/export semantics, with only local exports.
|
||||
const dfl=window.DFL;
|
||||
const spinnerClasses=dfl.findClassModule(module=>!!module.SpinnerLoaderContainer);
|
||||
assert.equal(spinnerClasses.ContainerBackground,'framey-loading');
|
||||
assert.equal(dfl.findClass('framey/spinner','Medium'),'framey-medium');
|
||||
assert.equal(dfl.findClassByName('LoadingStatus'),'framey-status');
|
||||
assert.equal(dfl.unminifyClass('framey-loading'),'ContainerBackground');
|
||||
assert.equal(dfl.findClassModule(module=>module.SteamOnlyClass),undefined);
|
||||
assert.equal(dfl.findClass('steam/unknown','Medium'),undefined);
|
||||
assert.equal(dfl.findClassByName('SteamOnlyClass'),undefined);
|
||||
const details=dfl.findModuleDetailsByExport((value,name)=>name==='Spinner' && typeof value==='function');
|
||||
assert.equal(details[0].Spinner,dfl.Spinner);
|
||||
assert.equal(details[1],dfl.Spinner);
|
||||
assert.equal(details[2],'Spinner');assert.equal(details[3],'framey/components');
|
||||
assert.equal(dfl.findModule(module=>module.Spinner),details[0]);
|
||||
assert.equal(dfl.findModuleByExport((value,name)=>name==='Spinner'),details[0]);
|
||||
assert.equal(dfl.findModuleChild(module=>module.Spinner),dfl.Spinner);
|
||||
assert.equal(dfl.findModuleExport((value,name)=>name==='Spinner',1000),undefined);
|
||||
assert.equal(dfl.findModuleExport(value=>value.prototype.nonexistent),undefined);
|
||||
assert.equal(dfl.findModuleChild(()=>false),undefined);
|
||||
const mapping=dfl.createModuleMapping(module=>!!module.SpinnerLoaderContainer);
|
||||
assert.equal(mapping.size,1);assert.equal(mapping.get('framey/spinner'),spinnerClasses);
|
||||
mapping.clear();assert.equal(dfl.findAllModules(module=>!!module.SpinnerLoaderContainer).length,1);
|
||||
assert.equal(dfl.createModuleMapping(module=>module.SteamOnlyClass).size,0);
|
||||
const audio=dfl.findModuleExport(value=>value.GamepadUIAudio).GamepadUIAudio;
|
||||
assert.equal(audio.available,false);
|
||||
assert.throws(()=>audio.AudioPlaybackManager.PlayAudioURL('file:///sound.wav'),/not supported in Framey/);
|
||||
assert.equal(dfl.findModuleExport(value=>value.m_GamepadUIAudioStore),undefined);
|
||||
assert.equal(dfl.findModuleExport(value=>value.toString?.().includes('().LibraryContextMenu')),undefined);
|
||||
assert.equal(window.DFL.findModuleChild(()=>true),null);
|
||||
window.DFL.Navigation.CloseSideMenus();
|
||||
assert.equal(nodes(window.__surface({plugin}),LocalRoute).length,0);
|
||||
undo();assert.equal(window.DFL.Navigation.Navigate('/plugin/details'),false);
|
||||
|
||||
@@ -49,7 +49,7 @@ context.SP_JSX=window.SP_JSX;
|
||||
vm.runInContext(official,context,{timeout:2000});
|
||||
const plugin=window.__official();
|
||||
assert.equal(typeof window.DFL.findModuleChild,'function');
|
||||
assert.equal(window.DFL.findModuleChild(()=>{}),undefined); // Steam has no matching module in the VR panel.
|
||||
assert.equal(window.DFL.findModuleChild(()=>{}),null); // Steam has no matching module in the VR panel.
|
||||
assert.equal(plugin.content?.type?.name,'QuickAccessView');
|
||||
const panel=plugin.content.type();
|
||||
assert.ok(panel?.type); // Read-only settings render with empty local data.
|
||||
|
||||
@@ -793,7 +793,7 @@
|
||||
"https://github.com/SteamDeckHomebrew/decky-loader"
|
||||
],
|
||||
"status": "broken",
|
||||
"reason": "This plugin needs root and is not supported by the Frame user service. Steam UI sound lookup is present as explicitly unsupported; the frontend still requires Steam m_GamepadUIAudioStore.m_AudioPlaybackManager, which is unavailable in the isolated panel.",
|
||||
"reason": "This plugin needs root and is not supported by the Frame user service. Frontend audit failed: Cannot read properties of null (reading 'm_GamepadUIAudioStore').",
|
||||
"blockInstall": true,
|
||||
"verification": [
|
||||
"static archive",
|
||||
@@ -804,7 +804,7 @@
|
||||
"id": 16,
|
||||
"name": "Audio Loader",
|
||||
"ready": false,
|
||||
"error": "Cannot read properties of undefined (reading 'm_AudioPlaybackManager')",
|
||||
"error": "Cannot read properties of null (reading 'm_GamepadUIAudioStore')",
|
||||
"logs": [
|
||||
{
|
||||
"kind": "warn",
|
||||
@@ -2784,7 +2784,7 @@
|
||||
"https://github.com/SteamGridDB/decky-steamgriddb"
|
||||
],
|
||||
"status": "broken",
|
||||
"reason": "Local module mapping is available; frontend still requires the Steam LibraryContextMenu implementation, which has no target in the isolated Framey panel.",
|
||||
"reason": "Frontend audit failed: DFL.createModuleMapping is not a function.",
|
||||
"blockInstall": false,
|
||||
"verification": [
|
||||
"static archive",
|
||||
@@ -2795,7 +2795,7 @@
|
||||
"id": 36,
|
||||
"name": "SteamGridDB",
|
||||
"ready": false,
|
||||
"error": "Cannot convert undefined or null to object",
|
||||
"error": "DFL.createModuleMapping is not a function",
|
||||
"logs": [],
|
||||
"methods": []
|
||||
},
|
||||
@@ -4403,8 +4403,8 @@
|
||||
"https://github.com/Tormak9970/TabMaster",
|
||||
"https://github.com/Tormak9970/TabMaster.git"
|
||||
],
|
||||
"status": "partial",
|
||||
"reason": "Local Chromium rendered the QAM and navigable Overview/Filters documentation with an actual Decky 3.3.0 amd64 backend. Library-tab editing remains unavailable: Steam login/library patches and MobX reactions have no target. ARM64 and worn VR unverified.",
|
||||
"status": "broken",
|
||||
"reason": "Frontend audit failed: Cannot read properties of null (reading 'GamepadUIAudio').",
|
||||
"blockInstall": false,
|
||||
"verification": [
|
||||
"static archive",
|
||||
@@ -4414,17 +4414,10 @@
|
||||
"browser": {
|
||||
"id": 61,
|
||||
"name": "TabMaster",
|
||||
"ready": true,
|
||||
"error": null,
|
||||
"logs": [
|
||||
{
|
||||
"kind": "error",
|
||||
"message": "%c TabMaster %c ERROR %c background: #ff6d05; color: black; background: #c70808; color: black; background: transparent; Could not find mobx.reaction"
|
||||
}
|
||||
],
|
||||
"methods": [
|
||||
"log_message"
|
||||
]
|
||||
"ready": false,
|
||||
"error": "Cannot read properties of null (reading 'GamepadUIAudio')",
|
||||
"logs": [],
|
||||
"methods": []
|
||||
},
|
||||
"archiveValidation": {
|
||||
"id": 61,
|
||||
@@ -6469,7 +6462,7 @@
|
||||
"https://github.com/ebenbruyns/junkstore.git"
|
||||
],
|
||||
"status": "broken",
|
||||
"reason": "Local CSS lookup fixes the loading view crash. Actual Decky 3.3.0 amd64 startup/static InitActions return a script execution/JSON error; the published scripts are not executable after extraction. Store install/login/game launch and ARM64 remain unverified.",
|
||||
"reason": "Route registration succeeds; rendering fails on a missing Steam ContainerBackground component.",
|
||||
"blockInstall": false,
|
||||
"verification": [
|
||||
"static archive",
|
||||
@@ -6481,10 +6474,14 @@
|
||||
"name": "Junk-Store",
|
||||
"ready": true,
|
||||
"error": null,
|
||||
"logs": [],
|
||||
"logs": [
|
||||
{
|
||||
"kind": "error",
|
||||
"message": "TypeError: Cannot read properties of null (reading 'ContainerBackground')"
|
||||
}
|
||||
],
|
||||
"methods": [
|
||||
"fetch_rss_feed",
|
||||
"execute_action"
|
||||
"fetch_rss_feed"
|
||||
]
|
||||
},
|
||||
"archiveValidation": {
|
||||
@@ -8476,7 +8473,7 @@
|
||||
"https://github.com/jessebofill/DeckSP.git"
|
||||
],
|
||||
"status": "broken",
|
||||
"reason": "Optional UI-audio lookup succeeds, but the published frontend raises \"Cannot access PluginManager before initialization\" when Steam MobX reaction lookup is unavailable. JamesDSP installation/audio routing and ARM64 remain unverified.",
|
||||
"reason": "Frontend audit failed: Cannot read properties of null (reading 'GamepadUIAudio').",
|
||||
"blockInstall": false,
|
||||
"verification": [
|
||||
"static archive",
|
||||
@@ -8487,7 +8484,7 @@
|
||||
"id": 102,
|
||||
"name": "DeckSP",
|
||||
"ready": false,
|
||||
"error": "Cannot access 'PluginManager' before initialization",
|
||||
"error": "Cannot read properties of null (reading 'GamepadUIAudio')",
|
||||
"logs": [],
|
||||
"methods": []
|
||||
},
|
||||
|
||||
+3
-66
@@ -288,50 +288,6 @@
|
||||
R.createElement('button', {type:'button',onClick:closeModal}, 'Close'), element));
|
||||
return {Close:closeModal};
|
||||
};
|
||||
// These are Framey's own styles and components, never Steam's webpack cache.
|
||||
// Keep the registry finite: an unknown Steam implementation stays unavailable.
|
||||
const classModules = new Map(Object.entries({
|
||||
'framey/spinner': {SpinnerLoaderContainer:'framey-spinner', ContainerBackground:'framey-loading',
|
||||
LoadingStatus:'framey-status', Medium:'framey-medium'},
|
||||
'framey/footer': {QuickAccessFooter:'framey-footer', BasicFooter:'framey-footer'},
|
||||
'framey/app-details': {AppDetailSectionList:'framey-sections', AppActionButton:'framey-action'},
|
||||
'framey/play-button': {PlayButtonContainer:'framey-actions', ButtonChild:'framey-button-child',
|
||||
Green:'framey-green', PlayButton:'framey-action'},
|
||||
'framey/library-image': {LongTitles:'framey-long-title', GreyBackground:'framey-muted', Image:'framey-image'},
|
||||
'framey/library': {GamepadLibrary:'framey-library'},
|
||||
'framey/focus': {FocusRingRoot:'framey-focus', FocusRing:'framey-focus'},
|
||||
}).map(([id, classes]) => [id, Object.freeze(classes)]));
|
||||
const localModules = new Map(classModules);
|
||||
const moduleVariants = module => [module?.default, module].filter(value => value != null);
|
||||
function findModule(filter) {
|
||||
for (const module of localModules.values())
|
||||
for (const value of moduleVariants(module)) if (filter(value)) return value;
|
||||
}
|
||||
function findModuleDetailsByExport(filter, minExports) {
|
||||
for (const [id, module] of localModules)
|
||||
for (const value of moduleVariants(module)) {
|
||||
if (typeof value !== 'object' || (minExports && Object.keys(value).length < minExports)) continue;
|
||||
for (const name in value) {
|
||||
if (!value[name]) continue;
|
||||
// DFL tolerates filters that dereference an incompatible export.
|
||||
try { if (filter(value[name], name)) return [value, value[name], name, id]; } catch (_) {}
|
||||
}
|
||||
}
|
||||
return [undefined, undefined, undefined, undefined];
|
||||
}
|
||||
function findModuleChild(filter) {
|
||||
for (const module of localModules.values())
|
||||
for (const value of moduleVariants(module)) {
|
||||
const result = filter(value);
|
||||
if (result) return result;
|
||||
}
|
||||
}
|
||||
function createModuleMapping(filter) {
|
||||
const mapping = new Map();
|
||||
for (const [id, module] of localModules)
|
||||
for (const value of moduleVariants(module)) if (filter(value)) mapping.set(id, value);
|
||||
return mapping;
|
||||
}
|
||||
const DFL = window.DFL = {
|
||||
definePlugin: init => init,
|
||||
PanelSection, PanelSectionRow: passthrough('div'), Field, ToggleField, DropdownItem,
|
||||
@@ -345,7 +301,6 @@
|
||||
DialogHeader:passthrough('h2'), DialogSubHeader:passthrough('h3'), DialogFooter:passthrough('footer'),
|
||||
DialogLabel:passthrough('label'), DialogControlsSection:passthrough('section'),
|
||||
DialogControlsSectionHeader:passthrough('h3'), ModalRoot:passthrough('section'),
|
||||
ModalPosition:passthrough('div'),
|
||||
Menu:passthrough('div'), MenuGroup:passthrough('section'), MenuItem,
|
||||
ProgressBar, ProgressBarWithInfo:ProgressBar,
|
||||
gamepadDialogClasses:{}, quickAccessMenuClasses:{}, gamepadTabbedPageClasses:{},
|
||||
@@ -359,30 +314,12 @@
|
||||
showModal, showContextMenu:showModal,
|
||||
// Steam app, library, and store patches have no target inside this panel.
|
||||
afterPatch:noPatch, beforePatch:noPatch, replacePatch:noPatch, createReactTreePatcher:noPatch,
|
||||
findInReactTree: () => null, findModule, findModuleChild, findModuleDetailsByExport,
|
||||
findModuleByExport:(filter, minExports)=>findModuleDetailsByExport(filter,minExports)[0],
|
||||
findModuleExport:(filter, minExports)=>findModuleDetailsByExport(filter,minExports)[1],
|
||||
createModuleMapping, findAllModules:filter=>[...createModuleMapping(filter).values()],
|
||||
findClassModule:filter=>[...classModules.values()].find(filter),
|
||||
findClass:(id,name)=>classModules.get(id)?.[name],
|
||||
findClassByName:name=>[...classModules.values()].find(classes=>classes[name])?.[name],
|
||||
unminifyClass:token=>{
|
||||
for(const classes of classModules.values())
|
||||
for(const name of Object.keys(classes)) if(classes[name]===token)return name;
|
||||
},
|
||||
findSP:()=>null, fakeRenderComponent:()=>null,
|
||||
findInReactTree: () => null, findModuleExport: () => null, findModuleChild: () => null,
|
||||
findModule:()=>null, findModuleByExport:()=>null, findClassModule:()=>null,
|
||||
findClass:()=>null, findSP:()=>null, fakeRenderComponent:()=>null,
|
||||
appDetailsClasses: {}, appDetailsHeaderClasses: {},
|
||||
useParams: () => currentParams,
|
||||
};
|
||||
localModules.set('framey/components', Object.freeze(Object.fromEntries(
|
||||
Object.entries(DFL).filter(([name,value])=>typeof value==='function' && /^[A-Z]/.test(name)))));
|
||||
// Some panels eagerly look up the optional Steam UI sound player. Allow the
|
||||
// lookup, but never claim playback or expose Steam's mutable audio store.
|
||||
localModules.set('framey/ui-audio', Object.freeze({UIAudio:Object.freeze({
|
||||
GamepadUIAudio:Object.freeze({available:false, AudioPlaybackManager:Object.freeze({
|
||||
PlayAudioURL:()=>{throw Error('Steam UI sound playback is not supported in Framey');},
|
||||
})}),
|
||||
})}));
|
||||
// No Steam game is attached to an isolated panel. Subscriptions have a
|
||||
// disposable handle but emit no fabricated game, power, or input events.
|
||||
const subscription = () => {const dispose=()=>{};dispose.unregister=dispose;return dispose;};
|
||||
|
||||
+1
-7
@@ -112,13 +112,7 @@ def panel(plugin_id):
|
||||
<title>Framey plugin</title><style>body{font:21px/1.4 system-ui;background:#0d1925;color:#f3f7fa;margin:0;padding:20px}
|
||||
button,select,input{font:inherit;min-height:52px;background:#23618c;color:#fff;border:1px solid #72baf0;border-radius:9px;padding:8px}
|
||||
button:focus-visible,select:focus-visible,input:focus-visible{outline:4px solid #f8d370}button{margin:4px 8px 4px 0}button:disabled{opacity:.55}section{padding:12px;margin:12px 0;background:#1b3042;border-radius:10px}
|
||||
label{display:grid;gap:6px;margin:10px 0}small{color:#b9c9d6}
|
||||
.framey-spinner,.framey-loading{display:grid;place-items:center;min-height:80px}.framey-loading{background:#1b3042}
|
||||
.framey-status{color:#b9c9d6}.framey-medium{font-size:1em}.framey-footer{padding:12px 0}
|
||||
.framey-sections,.framey-library{display:flex;flex-direction:column;gap:12px}.framey-actions{display:flex;flex-wrap:wrap;gap:8px}
|
||||
.framey-action{min-height:52px}.framey-button-child{display:inline-flex;align-items:center;gap:8px}.framey-green{background:#246b42}
|
||||
.framey-long-title{overflow-wrap:anywhere}.framey-muted{background:#1b3042}.framey-image{max-width:100%;object-fit:contain}
|
||||
.framey-focus:focus-visible{outline:4px solid #f8d370}</style>
|
||||
label{display:grid;gap:6px;margin:10px 0}small{color:#b9c9d6}</style>
|
||||
<p id="framey-error" role="status"></p><div id="framey-toasts" aria-live="polite"></div><div id="framey-root"></div><div id="framey-modal"></div>
|
||||
<script id="framey-bundle" type="application/json"''' + module + '''>''' + encoded + '''</script>
|
||||
<script src="/framey-runtime/react.js"></script><script src="/framey-runtime/react-dom.js"></script>
|
||||
|
||||
Reference in new issue
Block a user